dynamic button created in fragment disappears after re-entering the fragment - java

I have two classes. One extends FragmentActivity (MainActivity.java) and the other extends Fragment (HomeFragment.java). What I want is to create an image button in MainActivity and put it in home_fragment.xml and then update HomeFragment.java so that my imagebutton is permanently in the layout. Right now, I have a button, and add it to home_fragment.xml, and that works fine, but then if I leave that fragment and return back to it (through a button click), the button disappears.
Here is a picture of my interface. Where home_fragment is the white space with the "DriveDroid" button inside. And it is initiated when I click "Button 1". If I click button 2, 3, or 4 a different fragment is activated and if I go back to "Button 1", which opens home_fragment.xml, then the "DriveDroid" button is gone.
MainActivity is running a separate thread and listening on a port for an incoming image. Once it gets this image it creates an imagebutton with the image as the background. It adds this image button to an xml layout (home_fragment). This is all working correctly and this is the code I have for MainActivity:
private void RepeatTask()
{
repeatTaskThread = new Thread()
{
public void run()
{
while (true)
{
try {
System.out.println("TRY_1");
Socket socket = new Socket("72.120.55.34", 5050);
// Get data sent through socket
DataInputStream DIS = new DataInputStream(socket.getInputStream());
System.out.println("DataInputStream Started");
// read data that got sent
String applicationName = DIS.readUTF();
// read array data for bitmap
int len = DIS.readInt();
byte[] data = new byte[len];
DIS.readFully(data, 0, data.length);
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
final Drawable d = new BitmapDrawable(getResources(), bitmap);
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Log.d("tag_name", "Try_2");
ImageButton btn = new ImageButton(getApplicationContext());
//btn.setId(1);
btn.setBackgroundDrawable(d);
Log.d("tag_name", "Create Button" + btn);
ViewGroup RelativeLayout = (ViewGroup) findViewById(R.id.home_fragment);
btn.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
RelativeLayout.addView(btn);
Log.d("tag_name", "Button Added to View" + RelativeLayout);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
});
socket.close();
} catch (Exception e) {
System.out.println("Exception is "+e.toString());
}
try
{
// Sleep for 5 seconds
Thread.sleep(5000);
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
};
repeatTaskThread.start();
}
How can I get this image button to update in HomeFragment? And is this even what I should be doing? I just need my image button to now always appear whenever other parts of my code call on HomeFragment.
Here is how HomeFragment is called when Button1 is pushed (this code is in another fragment):
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fr_menu, container, false);
// get home image button
ImageButton Button1 = (ImageButton) view.findViewById(R.id.btnHOME);
// button listener
Button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container, new HomeFragment()).commit();
}
});

Related

Using Bundle to send data from activity to fragment

I am trying to use Bundle to send data from an activity to a fragment. The activity is receiving the input from a dialogbox when the user clicks on the actionbar add icon. The button also opens the dialogbox but it sends the data straight to the fragment (I'm trying to learn the difference between activity and fragment and to interact with the dialogfragment). None of the solutions on the internet have worked for me, and I was hoping someone can help
I have provided a visualization to aid in my explanation of the issue. So initially, I click the action add icon that opens the dialogbox (2nd pic), when I enter an input, it doesn't alter the data on the fragment. Only when I press the action add icon for a second time, does the first input get updated (3rd pic). Also you may notice that it says "Bundle{[Dialog Input = First Input]}" where First Input is the user input. How do I change this to just, First Input. I tried clearing the textview before setting the value, but that doesn't work. Now lastly when I press the button, it opens the dialogbox and when I enter in data, the data from the action add icon (handled in activity then data sent to fragment) overlaps with the data from the button (data sent straight to fragment). Any help would be appreciated. Thanks in advance.
MainActivity:
public class MainActivity extends AppCompatActivity implements
MyCustomDialog.OnInputSelected{
public String dialogInput;
FragmentManager fragmentManager;
#Override
public void sendInput(String input) {
dialogInput = input;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getSupportFragmentManager();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//Inflate the menu, this adds items to the action bar if it is present
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
//Handle action bar clicks here. The action bar will automatically handle clicks on the home/up button
//so long as you specify a parent activity in AndroidManifest.xml
switch(item.getItemId()){
case R.id.action_add:
MyCustomDialog dialog = new MyCustomDialog();
dialog.show(getSupportFragmentManager(), "MyCustomDialog");
//Trying Bundle to pass data, dialog input between activity and fragment
Bundle bundle = new Bundle();
bundle.putString("Dialog Input", dialogInput);
//Set Fragment class arguments
MainFragment fragment = new MainFragment();
fragment.setArguments(bundle); //set argument bundle to fragment
fragmentManager.beginTransaction().replace(R.id.MainFragment,fragment).commit(); //now replace Mainfragment
Toast.makeText(this, "Action_Add Clicked Successfully", Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
}
MainFragment:
public class MainFragment extends Fragment implements MyCustomDialog.OnInputSelected{
TextView InputDisplay;
Button OpenDialog;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
InputDisplay = view.findViewById(R.id.InputDisplay);
OpenDialog = view.findViewById(R.id.Open_Dialog);
//Getting Main Activity dialog information with Bundle, that was received from toolbar add
Bundle bundle = getArguments();
if(bundle != null){
String dialogInput = bundle.toString();
//Clearing since Fragment call and activity call overlap each other.
InputDisplay.setText("");
InputDisplay.clearComposingText();
InputDisplay.setText(dialogInput);
}
//String dialogInput = this.getArguments().getString("Dialog Input");
OpenDialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("MainFragment", "onClick: opening dialog");
MyCustomDialog customDialog = new MyCustomDialog();
customDialog.setTargetFragment(MainFragment.this, 1);
customDialog.show(getFragmentManager(), "MyCustomDialog");
}
});
return view;
}
#Override
public void sendInput(String input) {
InputDisplay.setText("");
InputDisplay.setText(input);
}
}
My Custom Dialog:
public class MyCustomDialog extends DialogFragment {
private EditText Input;
private TextView ActionOK, ActionCANCEL;
private OnInputSelected onInputSelected;
public interface OnInputSelected{
void sendInput(String input);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try{
Fragment onInputSelected_fragment = getTargetFragment();
Activity onInputSelected_activity = getActivity();
if(onInputSelected_fragment != null){
onInputSelected = (OnInputSelected) onInputSelected_fragment;
}else{
onInputSelected = (OnInputSelected) onInputSelected_activity;
}
//throw new RuntimeException("Custom Dialog onAttach Listener was NULL");
}catch(ClassCastException e){
Log.e("Custom Dialog", "onAttach: ClassCastException: " + e.getMessage());
}
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_my_custom, container, false);
Input = view.findViewById(R.id.Input);
ActionOK = view.findViewById(R.id.Action_OK);
ActionCANCEL = view.findViewById(R.id.Action_CANCEL);
ActionCANCEL.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getDialog().dismiss();
}
});
ActionOK.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onInputSelected.sendInput(Input.getText().toString());
getDialog().dismiss();
}
});
return view;
}
}
How do I change this to just, First Input.
your output is printed like this "Bundle{[Dialog Input = First Input]}" because you are directly doing bundle.toString(); instead of getting the value you have stored in the bundle.
change the above to this
String dialogInput = bundle.getString("Dialog Input")
InputDisplay.setText(dialogInput);
the data from the action add icon overlaps with the data from the button
Clear the existing text in the text view before setting the new value like this
String dialogInput = bundle.getString("Dialog Input")
InputDisplay.setText(");
InputDisplay.setText(dialogInput);
Also, I noticed that all the variable names that you have used are not following camel case I suggest you correct that as well.

I want to access values from a popup back to the activity from which the popup has been called

I've an Activity where I've a button which will lead to popup popup window in the same Activity. In that popup, I've multiple fields. And What I all want is to get back those values from popup to the same activity.
I've been stuck with it. Need a help :)
Related Code as follows.
This is the code in onCreate method for calling the popup.
Button button = (Button) findViewById(R.id.button9);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addProductDetails();
}
});
By calling addProductDetails() method popup gets displayed.
So in this method, the code as follows
private String addProductDetails() {
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.storeproductdetails_layout, (ViewGroup) findViewById(R.id.popup_element1), false);
final PopupWindow pwindo = new PopupWindow(layout, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
//get txt view from "layout" which will be added into popup window
//before it you tried to find view in activity container
/* Field Data */
product1Code = (EditText) layout.findViewById(R.id.productCodeee);
quantity1 = (EditText) layout.findViewById(R.id.quantityy);
details1 = (EditText) layout.findViewById(R.id.editText23);
orderValue1 = (EditText) layout.findViewById(R.id.editText36);
productC = String.valueOf(product1Code.getText());
qty = String.valueOf(quantity1.getText());
dts = String.valueOf(details1.getText());
orderVal = String.valueOf(orderValue1.getText());
StringBuffer sb = new StringBuffer("");
sb.append(productC+","+qty+","+dts+","+orderVal);
System.out.println("StringBuffer Value: "+sb.toString());
/* End of the field Data */
Button doneAddingProduct = (Button) layout.findViewById(R.id.doneAddingProduct);
//init your button
Button btnClosePopup = (Button) layout.findViewById(R.id.closePopup);
btnClosePopup.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
pwindo.dismiss();
}
});
doneAddingProduct.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
System.out.println("Inside onclick of done adding");
Product product = new Product();
product.setProductCode(productC);
product.setQuantity(qty);
product.setDetails(dts);
product.setOrderValue(orderVal);
app.setProduct(product);
Intent intent = new Intent(OrderReturnMgmtSecondActivity.this, OrderReturnMgmtSecondActivity.class);
startActivity(intent);
}
});
//show popup window after you have done initialization of views
pwindo.showAtLocation(layout, Gravity.CENTER, 0, 0);
return sb.toString();
}
Here I was trying to do is two methods in fetching those field data back to the activity.
1) Simply trying to return the field data by concatenating as a string to who ever calls this method.
2) Creating a pojo By the name as Product(which contains the field data) and setting it in application class i.e MyApplication extends Application ( you see that code as app.setProduct(product)) and redirecting it to the same activity and trying to fetch the data from that application.
But still I'm not able to get those field data.
Any help will be appreciated :)
Create an interface
interface Listener {
void onResult(Product product);
}
Pass a listener to the method and call it
addProductDetails(Listener listener){
//...
//when finished:
listener.onResult(product);
//...
}
The caller now has to implement the interface
addProductDetails(new Listener(){
void onResult(Product product){
//do something with product
}
});

ImageButton changing an Image of another ImageButton causes unintended cycle

Aftermath of this: Image for ImageButton doesn't change as intended
When ImageButton of "ibChamp" is clicked, it opens up champions.xml. In that layout, there is an Imagebutton called "ibAnnie". What I want that to do when clicked is, to change the image of "ibChamp", and to switch to that layout. What happened here is that after "ibAnnie" is clicked, it switches to "create_build_page.xml", and in that is a changed picture of "ibChamp". But that only happens for a split second before changing back to the original, unchanged picture, "create_build_page.xml" layout. When I click the back button, it goes to the "create_build_page.xml" layout with the changed picture, but the buttons do not work. I would gladly provide any additional information required.
I'm still not entirely clear on what you're trying to achieve... but if my understanding is correct, this should get you closer:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.champions);
ImageButton ibAnnie = (ImageButton) findViewById(R.id.ibAnnie);
ibAnnie.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
RelativeLayout test = (RelativeLayout) findViewById(R.id.layoutChampions);
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View createView = layoutInflater.inflate(R.layout.create_build_page, null);
test.addView(createView);
ImageButton img = (ImageButton) view.findViewById(R.id.ibChamp);
img.setImageResource(R.drawable.ic_launcher);
img.setTag(R.drawable.ic_launcher); // so you can retrieve it later
img.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// this will set the imageView of ibAnnie
ibAnnie.setImageView((Integer)view.getTag());
// this will remove the selection view from your layout
((RelativeLayout) findViewById(R.id.layoutChampions)).removeChild(createView);
}
});
// this opens another Activity... you don't want that, at least not for what you seem to be trying to do.
/*try {
Intent open = new Intent("android.intent.action.CREATE");
startActivity(open);
} catch (Exception e) {
}*/
}
});
}

PopUp window to be opened to touches within an Imageview

I have a big image which contains different sections. What I want is different PopUps should open when the user touches different sections of the ImageView. For instance, see this Image below:
In this image, what I want is that when the user clicks 1st square, Popup 1 should open, on square 2 popup should open. How to achieve this please.?
Moreover, I want the ImageView still be zoom and pan enabled. Please help.
Hello you can follow my this post . I think my answer will help you ::
popup window from android options menu not working
For you I have edited the code. You can follow in this manner. If button will be Image and replace button with that :
inside onCreate()
Button btn1=(Button) findViewById(R.id.btn1);
Button btn2=(Button) findViewById(R.id.btn2);
btn1.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
initiatePopupWindow1();
}
})
btn2.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
initiatePopupWindow2();
}
})
outside onCreate()
private PopupWindow pwindo1,pwindo2;
private void initiatePopupWindow1() {
try {
// We need to get the instance of the LayoutInflater
LayoutInflater inflater = (LayoutInflater) PopupActivity.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.popup,(ViewGroup)
findViewById(R.id.popup_element));
pwindo1 = new PopupWindow(layout, 350, 350, true);
pwindo1.showAtLocation(layout, Gravity.CENTER, 0, 0);
btnClosePopup = (Button) layout.findViewById(R.id.btn_close_popup);
btnClosePopup.setOnClickListener(cancel_button_click_listener);
} catch (Exception e) {
e.printStackTrace();
}
}
private void initiatePopupWindow2() {
try {
// We need to get the instance of the LayoutInflater
LayoutInflater inflater = (LayoutInflater) PopupActivity.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.popup,(ViewGroup)
findViewById(R.id.popup_element));
pwindo2 = new PopupWindow(layout, 350, 350, true);
pwindo2.showAtLocation(layout, Gravity.CENTER, 0, 0);
btnClosePopup = (Button) layout.findViewById(R.id.btn_close_popup);
btnClosePopup.setOnClickListener(cancel_button_click_listener);
} catch (Exception e) {
e.printStackTrace();
}
}
You can use (though it doesn't seem to be the best way of what actually you are trying to achieve but still you can have a single image)
setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
and the event.getX() and event.getY() will give you the coordinates where you are clicking
for example
if(event.getX() == 100 and event.getY() == 100)
{ // show your popup}
But there will be a problem if you have multiple images
you have to know at what positions these boxes will be present, and you might face problem if the image is to zoomed

Using android-color-picker in a fragment?

I am fairly new to android development and want to use the Android-Color_picker "AmbilWarna" inside a fragment. I am getting the error:
The constructor AmbilWarnaDialog(HomeFragment, int, new OnAmbilWarnaListener(){}) is undefined.
Is this because I am using a Fragment instead of a Fragment activity The tutorial I was using uses an Activity.
I am using the following tutorial:
http://wptrafficanalyzer.in/blog/android-color-picker-application-using-ambilwarna-color-picker-library/
public class HomeFragment extends SherlockFragment implements TabListener {
private View homeView;
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
homeView = inflater.inflate(R.layout.homefragment, container, false);
Button sColorBtn = (Button) homeView.findViewById(R.id.button2);
OnClickListener clickListener = new OnClickListener() {
#Override
public void onClick(View v) {
colorpicker();
}
};
// Setting click event listener for the button
sColorBtn.setOnClickListener(clickListener);
return sColorBtn;
}
public void colorpicker() {
// initialColor is the initially-selected color to be shown in the rectangle on the left of the arrow.
// for example, 0xff000000 is black, 0xff0000ff is blue. Please be aware of the initial 0xff which is the alpha.
AmbilWarnaDialog dialog = new AmbilWarnaDialog(this, 0xff0000ff, new OnAmbilWarnaListener() {
// Executes, when user click Cancel button
#Override
public void onCancel(AmbilWarnaDialog dialog){
}
// Executes, when user click OK button
#Override
public void onOk(AmbilWarnaDialog dialog, int color) {
Toast.makeText(getBaseContext(), "Selected Color : " + color, Toast.LENGTH_LONG).show();
}
});
dialog.show();
}
Use this:
AmbilWarnaDialog dialog = new AmbilWarnaDialog(getActivity().getApplicationContext(), 0xff0000ff, new OnAmbilWarnaListener() {
// Executes, when user click Cancel button
#Override
public void onCancel(AmbilWarnaDialog dialog){
}
// Executes, when user click OK button
#Override
public void onOk(AmbilWarnaDialog dialog, int color) {
Toast.makeText(getBaseContext(), "Selected Color : " + color, Toast.LENGTH_LONG).show();
}
});
So you have to use getActivity().getApplicationContext() instead of this. It will return with the Context.
If you want a fragment solution for Color Picker, I have made a fork of android-color-picker where DialogFragment is used and is re-created on configuration change. Here's the link: https://github.com/lomza/android-color-picker

Categories