Search code examples
androidonclicklistenerlistadapterandroid-listfragment

Is it possible to get a Button view from ListView Fragment instead of ListView Adapter?


I have this:

enter image description here

Where Red square is the activity containing several fragments, almost all of them are lists, all of them with different items but built by my custom ListAdapter class.

Orange square is one of those fragments, actually it's a right drawer. This fragment extends from ListFragment, and inflates a simple xml without Items.

Inside of the fragment's onActivityCreated I instantiate a custom ListAdapter which I fill with the items you see in the screenshot.

I have several xml depending on the type of Item I want, here you can see 3 of them:

  • Button Title (The green square)
  • Checkable item (The ones which can have the checked icon at right)
  • Regular Title (The one that says "Día y hora del viaje")

Button title (Green square) xml is a simple linear layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/menu_row_title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <ImageButton
        android:id="@+id/row_button"
        android:layout_width="45dp"
        android:layout_height="45dp"
        android:padding="10dp" />

    <TextView
        android:id="@+id/row_title"
        android:layout_width="0px"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:minLines="1"
        android:padding="10dp"
        android:textAppearance="@android:style/TextAppearance.Medium"
        android:textStyle="bold" />

</LinearLayout>

What I want to do is to access the button from the orange square (my custom ListFragment class) to set a click listener. I have made my research and I know I can do it (I have succesfully tried) from the adapter, but that's what I don't want, because in other menus I'm going to have other buttons that behave different but they're going to call same listener because they are built by same adapter.

I have tried after inflating the Fragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View fragmentView = inflater.inflate(R.layout.menu_list, null); 
    //Button of location settings
    ((ImageButton)fragmentView.findViewById(R.id.row_button)).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
                //Do here stuff I want to
        }
    }); 
    super.onStart();
    return fragmentView;
}

Also from onStart:

@Override
public void onStart() {
    //Button of location settings
    ((ImageButton)getView().findViewById(R.id.row_button)).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
                //Here my stuff
        }
    }); 
    super.onStart();
}

and also after the setListAdapter()

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    //A new instance of my own ListAdapter
    MyListAdapter adapter = new MyListAdapter(getActivity());
    //Prepare my items and its propierties within adapter
    //...
    //Set the Adapter
    setListAdapter(adapter);
    //And then try to get the Button view
    //Button of location settings
    ((ImageButton)getView().findViewById(R.id.row_button)).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            //My stuff here
        }
    }); 
}

But guess what... I always get same error in xml inflating the fragment. If I remove the lines of setting the click listener, it works, but obviously the button does nothing.

Any help is greatly appreciated.


Solution

  • Here is the answer from the comments :

    Your button is located in a row of your ListView, so you can only find it from your list adapter (in getView()). Calling findViewById() from your fragment can't return views contained in your ListView.

    One solution is to set a tag to your button when you inflate it, and then do something depending on the tag when the button is clicked.