Onclicklistner not working in fragment listview
Asked Answered
C

10

5

I have a listview with custom adapter in listfragment and also set onclicklistner for listview. But Onclicklistner does not work.

Here is my code:

public class BasicFragment extends ListFragment {

ListView lv;
MyCustomAdapter adapter;

@Override
public void onCreate(Bundle si) {
    super.onCreate(si);
}

@Override
public void onActivityCreated(Bundle b) {
    super.onActivityCreated(b);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_basic, container, false);
    lv = (ListView) view.findViewById(android.R.id.list);
    FetchedData DT = FetchedData.StaticDataTransfer();
    RecepiesProperties[] AryObjaz = DT.getData();
    getdata(AryObjaz);
    adapter = new MyCustomAdapter(getActivity(), R.layout.listview_layout,
            Dataset);
    lv.setAdapter(adapter);

    lv.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            Toast t = Toast.makeText(getActivity(), "Message",
                    Toast.LENGTH_SHORT);
            t.show();
        }
    });

    return view;
}}

MyCustomAdapter.java

public class MyCustomAdapter extends ArrayAdapter<Recipes> {

Context context;
int layoutResourceId;
Recipes data[] = null;
Typeface typeface;
public ImageLoader imageLoader;

public MyCustomAdapter(Context context, int textViewResourceId,
        Recipes[] dataset) {
    super(context, textViewResourceId, dataset);
    this.layoutResourceId = textViewResourceId;
    this.context = context;
    this.data = dataset;
    imageLoader = new ImageLoader(context.getApplicationContext());
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;

    LayoutInflater inflater = ((Activity) context).getLayoutInflater();
    row = inflater.inflate(layoutResourceId, parent, false);
    RecipesHolder holder = new RecipesHolder();
    holder.imgIcon = (ImageView) row.findViewById(R.id.imageView1);
    holder.txtTitle = (TextView) row.findViewById(R.id.title);
    holder.category = (TextView) row.findViewById(R.id.category);
    holder.source = (TextView) row.findViewById(R.id.source);
    holder.country = (TextView) row.findViewById(R.id.country);
    holder.readytime = (TextView) row.findViewById(R.id.readytime);
    holder.tips = (Button) row.findViewById(R.id.tips);
    holder.fav = (Button) row.findViewById(R.id.fav);

    Recipes ap = data[position];

    imageLoader.DisplayImage(ap.getIMAGENAME240(), holder.imgIcon);
    holder.txtTitle.setText(ap.getNAME());
    holder.category.setText(ap.getCATEGORY());
    holder.source.setText(ap.getSOURCE());
    holder.country.setText(ap.getCOUNTRY());
    holder.readytime.setText(ap.getREADYTIME());

    return row;
}

static class RecipesHolder {
    ImageView imgIcon;
    TextView txtTitle;
    TextView category;
    TextView source;
    TextView country;
    TextView readytime;
    Button tips;
    Button fav;
}}

//listview_layout.xml

<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"><ImageView
    android:id="@+id/imageView1"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_alignParentLeft="true"
    android:focusable="true"
    android:layout_alignParentTop="true"
    android:layout_marginLeft="5dp"
    android:layout_marginTop="10dp" />

<TextView
    android:id="@+id/readytime"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBaseline="@+id/country"
    android:layout_alignBottom="@+id/country"
    android:layout_marginLeft="73dp"
    android:layout_toRightOf="@+id/country"
    android:focusable="true"
    android:text="TextView"
    android:textColor="#000" />

<TextView
    android:id="@+id/country"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@+id/imageView1"
    android:layout_alignLeft="@+id/source"
    android:focusable="true"
    android:text="TextView"
    android:textColor="#000" />

<TextView
    android:id="@+id/source"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_above="@+id/country"
    android:layout_alignLeft="@+id/category"
    android:focusable="true"
    android:text="TextView"
    android:textColor="#000" />

<TextView
    android:id="@+id/category"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_above="@+id/source"
    android:layout_alignLeft="@+id/title"
    android:text="TextView"
    android:focusable="true"
    android:textColor="#000" />

<TextView
    android:id="@+id/title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_above="@+id/category"
    android:layout_toRightOf="@+id/imageView1"
    android:text="TextView"
    android:focusable="true"
    android:textColor="#000" />

<Button
    android:id="@+id/fav"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/tips"
    android:layout_below="@+id/source"
    android:focusable="true"
    android:background="@drawable/favourite" />

<Button
    android:id="@+id/tips"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_alignTop="@+id/textView1"
    android:layout_marginRight="14dp"
    android:background="@drawable/yellow" /></RelativeLayout>
Cott answered 27/2, 2013 at 14:1 Comment(1)
Did you try declaring the listener inside onViewCreated(View view, Bundle savedInstanceState)? And not inside onCreateView(). It shouldn't live in that onViewCreate() method.Farther
C
13

finally solved the issue when all the controls(Buttons,textviews) in listview set to focusable false.

Cott answered 5/3, 2013 at 15:34 Comment(2)
Thanks! This helped me after an hour of debugging...!Politicize
This worked for me as well! I use the code android:focusable="false" to all Buttons and TextViews inside my XML that is associated with my fragment class.Serrano
A
7

Check your MyCustomAdapter, Some widget (such as: Button,ImageButton) in the custom layout will consume the click event and then the onItemClick will never get called.

Use the following code in your adaper's getView method to get the onClick event.

     row.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

        }
    });
Aloysia answered 27/2, 2013 at 14:40 Comment(0)
C
6

As per the Android API Doc:

ListFragment has a default layout that consists of a single list view. However, if you desire, you can customize the fragment layout by returning your own view hierarchy from onCreateView(LayoutInflater, ViewGroup, Bundle). To do this, your view hierarchy must contain a ListView object with the id "@android:id/list" (or list if it's in code)

Since you did not post the layout file for the fragment i am not sure what went wrong here. The following code is how it should be when you are using the default list view of ListFragment. If you are using the ListFragment you should leverage the additional methods available like setListAdapter and onListItemClick. You can additionally do the same thing without using a ListFragment (Using just Fragment).

The Fragment Code (Modified your piece of code)

public class BasicFragment extends ListFragment {

    MyCustomAdapter adapter;

    @Override
    public void onCreate(Bundle si) {
        super.onCreate(si);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        // not sure what you are doing here but data fetch should be asynchronous if it interacts with DB or makes network call
        FetchedData DT = FetchedData.StaticDataTransfer();
        RecepiesProperties[] AryObjaz = DT.getData();
        getdata(AryObjaz);
        adapter = new MyCustomAdapter(getActivity(), R.layout.listview_layout, Dataset);
        setListAdapter(adapter);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        Toast t = Toast.makeText(getActivity(), "Message",
        Toast.LENGTH_SHORT);
        t.show();

    }
}

Additionally i modified your adapter code to help recycle views, your current code was not using view recycling and was always inflating views.

Adapter code:

public class MyCustomAdapter extends ArrayAdapter<Recipes> {

    Context context;
    int layoutResourceId;
    Recipes data[] = null;
    Typeface typeface;
    public ImageLoader imageLoader;
    private LayoutInflater inflater;

    public MyCustomAdapter(Context context, int textViewResourceId, Recipes[] dataset) {
        super(context, textViewResourceId, dataset);
        this.layoutResourceId = textViewResourceId;
        this.context = context;
        this.data = dataset;
        imageLoader = new ImageLoader(context.getApplicationContext());
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        RecipesHolder holder = null;
        //recycling views
        if(null == row){
            row = inflater.inflate(layoutResourceId, parent, false);
            holder = new RecipesHolder();
            holder.imgIcon = (ImageView) row.findViewById(R.id.imageView1);
            holder.txtTitle = (TextView) row.findViewById(R.id.title);
            holder.category = (TextView) row.findViewById(R.id.category);
            holder.source = (TextView) row.findViewById(R.id.source);
            holder.country = (TextView) row.findViewById(R.id.country);
            holder.readytime = (TextView) row.findViewById(R.id.readytime);
            holder.tips = (Button) row.findViewById(R.id.tips);
            holder.fav = (Button) row.findViewById(R.id.fav);
            row.setTag(holder);
        }else{
            holder = (RecipesHolder)row.getTag();
        }
        Recipes ap = data[position];

        imageLoader.DisplayImage(ap.getIMAGENAME240(), holder.imgIcon);
        holder.txtTitle.setText(ap.getNAME());
        holder.category.setText(ap.getCATEGORY());
        holder.source.setText(ap.getSOURCE());
        holder.country.setText(ap.getCOUNTRY());
        holder.readytime.setText(ap.getREADYTIME());

        return row;
    }

    static class RecipesHolder {
        ImageView imgIcon;
        TextView txtTitle;
        TextView category;
        TextView source;
        TextView country;
        TextView readytime;
        Button tips;
        Button fav;
    }
}
Carp answered 5/3, 2013 at 11:53 Comment(0)
S
4

When you are inflating your views, it seems that your view has 2 Buttons in it:

this row.findViewById(R.id.tips);

and this row.findViewById(R.id.fav);

You should either remove these buttons (replace them with textviews if you do not want their click)

Or if you want the clicks of these buttons, you can use OnClickListeners for each button and another OnClickListener for the whole view.


EXAMPLE

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;

    //we only inflate if the row is null!!
    if(row == null) {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);
        RecipesHolder holder = new RecipesHolder();
        holder.imgIcon = (ImageView) row.findViewById(R.id.imageView1);
        holder.txtTitle = (TextView) row.findViewById(R.id.title);
        holder.category = (TextView) row.findViewById(R.id.category);
        holder.source = (TextView) row.findViewById(R.id.source);
        holder.country = (TextView) row.findViewById(R.id.country);
        holder.readytime = (TextView) row.findViewById(R.id.readytime);
        holder.tips = (Button) row.findViewById(R.id.tips);
        holder.fav = (Button) row.findViewById(R.id.fav);
        //we set the tag of the view to this holder so we can get it everytime
        row.setTag(holder);
    }
    //change this to final so that you can use it inside your click listeners
    final Recipes ap = data[position];

    //here we get the holder of the view from its tag
    RecipesHolder holder = (RecipesHolder) row.getTag();

    //no changes to ur setup
    imageLoader.DisplayImage(ap.getIMAGENAME240(), holder.imgIcon);
    holder.txtTitle.setText(ap.getNAME());
    holder.category.setText(ap.getCATEGORY());
    holder.source.setText(ap.getSOURCE());
    holder.country.setText(ap.getCOUNTRY());
    holder.readytime.setText(ap.getREADYTIME());

    //now the click listeners

    //tips button
    holder.tips.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            //tips has been clicked
            //do whatever you want with `ap`
        }
    });
    //fav button
    holder.fav.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            //fav has been clicked
            //do whatever you want with `ap`
        }
    });
    //whole item click
    row.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            //the row has been clicked
            //do whatever you want with `ap`
        }
    });
    return row;
}
Seow answered 4/3, 2013 at 13:51 Comment(5)
@Cott where are the buttons with android:id="@+id/fav" and android:id="@+id/tips"Seow
now see listview_layout.xml. i need clicks of buttons in listview and listview row tooCott
@Cott I have edited the answer and fixed your getView function. The comments should give you a better understanding of Holder and of course the click listenersSeow
thaks for response i need to show another fragment while click that listview row. what can i do for that?Cott
let us continue this discussion in chatSeow
F
3

Put the following code in onViewCreated() method:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {

    ListView list = (ListView) view.findViewById(android.R.id.list);

    list.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
                      Toast t = Toast.makeText(getActivity(), "Message",
                             Toast.LENGTH_SHORT);
                      t.show();
        }
    }); 

}

The problem may lie in the fact that the view is not constructed yet in onViewCreate(), so it's not advisable to set the listeners there.

Farther answered 27/2, 2013 at 14:13 Comment(5)
Thanks for your response. i have implement this method but not working. please give any sample.Cott
The Toast isn't appearing?Farther
yes.toast not appear. i have use CustomAdapter for listview.Cott
Show us your "MyCustomAdapter" class.Farther
Please see MyCustomAdapter class.Cott
A
2
 lv.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
                //your code
        }
   });

I think this should work

Assumed answered 27/2, 2013 at 14:24 Comment(0)
S
2

Adapter has method areAllItemsEnabled (), it might be useful.

public abstract boolean areAllItemsEnabled ()

Indicates whether all the items in this adapter are enabled. If the value returned by this method changes over time, there is no guarantee it will take effect. If true, it means all items are selectable and clickable (there is no separator.)

Stiffnecked answered 10/3, 2013 at 11:42 Comment(0)
I
1
@Override

public void onListItemClick(ListView l, View v, int position, long id) {
    // TODO Auto-generated method stub
    super.onListItemClick(l, v, position, id);
}
Inexpensive answered 27/2, 2013 at 14:21 Comment(0)
A
0

Just put android:focusable="false" android:clickable="false" in layout. For all textviews,buttons etc. Problem Solved.

Arica answered 9/12, 2013 at 6:17 Comment(0)
T
0

I had a similar issue, it took me a very long time to figure out what was wrong. Previously my fragment's onListItemClick() opened new activity, but after returning to the fragment the onListItemClick() listener did not work anymore.

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    // additional code (e.g. open new activity)
}

This issue was solved by creating a listener inside my custom ArrayAdapter instead. I placed this code inside of getView():

    rowView.setOnClickListener(new View.OnClickListener() {
        final int p = position;
        @Override
        public void onClick(View v) {
            Log.d("FeedListAdapter", "onClick()");
            openPost(p);    // for example
        }
    });

I've stayed up all night fixing this (it's 8am), I thought I should post my solution for anyone else who is in a similar spot :)

Theorbo answered 27/3, 2017 at 7:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.