I'm using a fragment to show a GridView with some images and a Button to add new Images. The GridView works fine, but my Button's onClick method is never called.
This is my Fragment's onCreateView method:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_picture_grid_view, container, false);
addPictureButton = (Button) rootView.findViewById(R.id.fragment_grid_view_add_button);
addPictureButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CameraOrAlbumDialogFragment dialogFragment = new CameraOrAlbumDialogFragment();
dialogFragment.show(mContext.getSupportFragmentManager(), "CameraPicker");
}
});
imageGridView = (GridView) rootView.findViewById(R.id.fragment_grid_view);
imageGridView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
}
In my onActivityCreated method I do all the Adapter stuff for my GridView and it works normally, it can capture my clicks and longClicks. The only thing not working is the Button's onCLick method. I can see the Button icon changing when I touch it, but the functions inside my onClickListener method are never called. Any help?
EDIT
This is my fragment layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<GridView
android:id="#+id/fragment_grid_view"
android:layout_width="match_parent"
android:layout_height="150dp"
android:numColumns="auto_fit" >
</GridView>
<Button
android:id="#+id/fragment_grid_view_add_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Add Picture" />
</LinearLayout>
EDIT2
Turns out that there was another button overlaping my button, so that button was receiving the onClick events instead of my button. I was able to figure it out when I used the Hierarchy view in Eclipse. Very usefull.
Try this.
public class CarCheckFrameFragment extends Fragment implements View.OnClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View rootView = inflater.inflate(R.layout.fragment_car_check_frame, container, false);
Button button = rootView.findViewById(R.id.button);
button.setOnClickListener(this);
return rootView;
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.button:
doSomething();
break;
}
}
}
I figured thet I had another View overlapping my button, that's why it was never called.
SO DUMB! Sorry.
You should use getChildFragmentManager() when using fragments inside other fragments.
Related
I have a problem when I insert this code in the fragment
public class CameraConnectionFragment extends Fragment{
boolean clicked = false;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.camera_connection_fragment, container, false);
Button button = (Button) view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
clicked = true;
}
});
return view;
}
}
The problem is essentialy that the variable clicked doesn't change when I press the button when the application is running. I've put an if statement which evaluate the clicked variable but it's always set to false even if I keep pressing the button.
The code where the button is located (camera_connection_fragment) is the following:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.tensorflow.demo.AutoFitTextureView
android:id="#+id/texture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
<org.tensorflow.demo.RecognitionScoreView
android:id="#+id/results"
android:layout_width="match_parent"
android:layout_height="112dp"
android:layout_alignParentTop="true" />
<org.tensorflow.demo.OverlayView
android:id="#+id/debug_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="25dp"
android:layout_marginEnd="135dp"
android:text="Button"
android:onClick="getMe"/>
</RelativeLayout>
Do you have any idea why this is happening?
Where do you put the if statement that checks the clicked variable? Maybe, your code already passes the if statement before your click listener is triggered. Look at the following code:
boolean clicked = false;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.camera_connection_fragment, container, false);
Button button = (Button) view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//Put your logic in the if(clicked) control.
clicked = true // you can delete this line
(your logic)
}
});
return view;
}
#Override
protected void onStart() {
super.onStart();
//You can delete the below if check and move your logic to onClick method
if(clicked) {
(your logic)
}
}
In the above code, clicked variable check in onStart always false, since it is already executed before your click listener is triggered. If it is possible you can check clicked variable in click listener's onClick method. If you share the place where you put your if logic we can provide more proper answer.
I'm trying to remove a layout with the click of a button.
I have this method in my MainActivity.java file:
public void goBack(View view) {
TableLayout parent = (TableLayout) findViewById(R.id.activity_main);
RelativeLayout child = (RelativeLayout) findViewById(R.id.activity_displayMessage);
parent.removeView(child);
}
It is fired when this button is clicked in the view I want to remove:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_removeView"
android:onClick="goBack" />
But it gives me this message:
java.lang.IllegalStateException: Could not find method goBack(View) in
a parent or ancestor Context for android:onClick
But MainActivity is my main file for all my methods, so I'm not sure why it can't find it.
Where should I put it so that it can be found?
Thanks!
To avoid such problems remove onClick from Layout and instead of that add OnClickListener programmically.
First add id to element
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_removeView"
android:id="#+id/button"
/>
Second add listener
getView().findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//here Your code
}
});
In case of using fragment best place will be onCreateView method:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_layout, container, false);
v.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//here Your code
}
});
return v;
}
You can also set fragment as listener like:
v.findViewById(R.id.button).setOnClickListener(this);
and in this case fragement must implement OnClickListener interface.
Use parent.removeViewAt(0) where '0' is the index of the child . It removes the view at particular index .
I create two fragments:
<fragment
android:name="BoxFragment"
android:layout_width="150dp"
android:layout_height="80dp"
android:id="#+id/box_fragment_1"
android:layout_below="#+id/box_fragment_2"
android:layout_alignParentStart="true"
android:layout_marginTop="42dp"
tools:layout="#layout/fragment_box" />
<fragment
android:layout_width="150dp"
android:layout_height="50dp"
android:id="#+id/box_fragment_2"
android:layout_centerVertical="true"
android:layout_alignParentStart="true"
tools:layout="#layout/fragment_box" />
Layout of this fragments:
<ImageButton
android:layout_width="197dp"
android:layout_height="197dp"
android:id="#+id/ibPress"
android:layout_gravity="center" />
So, i register OnClickListener:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_box, container, false);
ImageButton imageButton= (ImageButton) view.findViewById(R.id.ibPress);
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i(LOG_TAG,this.toString());
//how to know,wich button clicked?
presenter.onButtonClick(...?);
}
});
return view;
}
So, i want to know from what fragment button was pressed?
Should i need to reference View into presenter.onButtonClick?
At presenter, i want to know what button was pressed and then do some work.
Thank you!
You can modify your presenter.onButtonClick() by
presenter.onButtonClick(int fragmentId) or presenter.onButtonClick(String fragmentTagName)
Then in that method using switch case you can perform the action based on the id or tag of that particular fragment.
You can get the id of the currently clicked view using getId().See the code below.
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.b1:
// it was the first button
break;
case R.id.b2:
// it was the second button
break;
}
}
}
Please read the docs for more info.
I have a fragment with his class:
public class FormatShortFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.bag_format_short, container, false);
return rootView;
}
}
And this is his layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</LinearLayout>
</RelativeLayout>
This fragment is shown by a FragmentPageAdapter.
The layout will grow when an user add an item from server (the origin of the item doesn't matter), and this item will be an horizontal linearlayout, with textview and edittext (item_name, item_value). This value can be modifiable, so must be an edittext, also, this edittext will receive values periodically from server, so can be updated automatically.
After explain this, how can I add this linearLayouts and his subviews to the GUI dynamically? and when should I update the interface?
Thanks a lot, any help is good received, I'm really lost on this on this themes.
EDITED WITH MODIFICATIONS:
I have modified the code in this way:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.bag_format_short, container, false);
return rootView;
}
#Override
public void onResume() {
super.onResume();
LinearLayout parentLinear = (LinearLayout) getActivity().findViewById(R.id.short_container);
for (int i = 1; i<10; i++ ){
LinearLayout innerLinear = (LinearLayout) new LinearLayout(getActivity());
TextView itemName = new TextView(getActivity());
itemName.setText("Nombre");
EditText itemValue = new EditText(getActivity());
itemValue.setText("Valor");
innerLinear.addView(itemName);
innerLinear.addView(itemValue);
parentLinear.addView(innerLinear);
}
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onStop() {
super.onStop();
}
And the fragment layout has been modified on this way:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<LinearLayout
android:id="#+id/short_container"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</LinearLayout>
</RelativeLayout>
Now the layout is growing in each for iteration.
In this point i have another problems, I hope you can help me with this.
- How can I generate a LayouParams object with attributes like gravity or weigth?
- How can I pass data from MainActivity to the Fragment?
- And how can i force the Fragment view to be raloaded with new data?
Also i need to know how bind a clickListener event to programatically linearLayouts added, i need modify some values on server depending on the name and the edited value.
Thanks a lot for this, you are saving my life.
you Can easily Update UI of Fragment on Button click or any event just
Like in Activity. You can get any view by
getActivity().findViewById()
See Example, It will help you to undersatand:-
public class FragmentTab3 extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragmenttab3, container, false);
return rootView;
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onStart() {
super.onStart();
LinearLayout linear = (LinearLayout) getActivity().findViewById(R.id.linear);
Button button = new Button(getActivity());
button.setText("Click Me");
linear.addView(button);
}
#Override
public void onStop() {
super.onStop();
}
}
If you want to add subview to a layout dynamically, take a look at RecyclerView in android documentation. Sounds like what you're looking for.
I have a listview in Fragment.
In my listitem layout contains three buttons,like:
<LinearLayout
android:id="#+id/back"
android:layout_width="match_parent"
android:layout_height="#dimen/msg_item_h">
<Button
android:layout_width="#dimen/msg_delete_btn_w"
android:layout_height="#dimen/msg_delete_btn_w"
android:id="#+id/btnDelete"
android:onClikc="onDeleteClick"
android:text="delete" />
<Button
android:layout_width="#dimen/msg_delete_btn_w"
android:layout_height="#dimen/msg_delete_btn_w"
android:id="#+id/btnAdd"
android:onClikc="onAddClick"
android:text="add" />
<Button
android:layout_width="#dimen/msg_delete_btn_w"
android:layout_height="#dimen/msg_delete_btn_w"
android:id="#+id/btnEdit"
android:onClikc="onEditClick"
android:text="edit" />
I want to handle the event onDeleteClick,onEditClick and onAddClick in my fragment.
But everytime the fragmentActivity got the event.
Is there a way to solve it?
You can do something like this in your fragment:
view.findViewById(R.id.btnDelete).setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View v) {
//Do your stuff here
}
});
If you do this you wouldn't need android:onClick="onDeleteClick" anymore.
The following solution handles onClick events, and works for Activity as well as Fragments:
public class YourFragmentClass extends Fragment implements OnClickListener{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_xml_file, container, false);
Button delete = (Button) view.findViewById(R.id.btnDelete);
delete.setOnClickListener(this);
return view;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnDelete:
// Do something here...
break;
}
}
}
android:onClick delivers the event to the Context, so this is impossible.
According to View documentation:
Name of the method in this View's context to invoke when the view is clicked. This name must correspond to a public method that takes exactly one parameter of type View. For instance, if you specify android:onClick="sayHello", you must declare a public void sayHello(View v) method of your context (typically, your Activity).