5

我在 listfragment 中有一个带有自定义适配器的 listview,并且还为 listview 设置了 onclicklistner。但是 Onclicklistner 不起作用。

这是我的代码:

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>
4

10 回答 10

13

当listview中的所有控件(按钮,textviews)设置为focusable false时,终于解决了这个问题。

于 2013-03-05T15:34:39.647 回答
7

检查您的 MyCustomAdapter,自定义布局中的某些小部件(例如:Button、ImageButton)将消耗点击事件,然后永远不会调用 onItemClick。

在您的适配器的 getView 方法中使用以下代码来获取 onClick 事件。

     row.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

        }
    });
于 2013-02-27T14:40:39.177 回答
6

根据 Android API 文档:

ListFragment 具有由单个列表视图组成的默认布局。 但是,如果您愿意,您可以通过从 onCreateView(LayoutInflater, ViewGroup, Bundle) 返回您自己的视图层次结构来自定义片段布局。为此,您的视图层次结构必须包含一个 ID 为“@android:id/list”的 ListView 对象(如果它在代码中,则为列表)

由于您没有发布片段的布局文件,我不确定这里出了什么问题。以下代码是您使用 ListFragment 的默认列表视图时的样子。如果您使用 ListFragment,您应该利用可用的其他方法,例如setListAdapteronListItemClick。您还可以在不使用 ListFragment(仅使用 Fragment)的情况下做同样的事情。

片段代码(修改了您的代码)

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();

    }
}

此外,我修改了您的适配器代码以帮助回收视图,您当前的代码没有使用视图回收并且总是在膨胀视图。

适配器代码:

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;
    }
}
于 2013-03-05T11:53:48.387 回答
4

当您夸大您的视图时,您的视图中似乎有 2 个按钮:

row.findViewById(R.id.tips);

还有这个row.findViewById(R.id.fav);

您应该删除这些按钮(如果您不想点击它们,请将它们替换为文本视图)

或者,如果您想要点击这些按钮,您可以对每个按钮使用 OnClickListeners,对整个视图使用另一个 OnClickListener。


例子

@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;
}
于 2013-03-04T13:51:07.193 回答
3

将以下代码放入onViewCreated()方法中:

@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();
        }
    }); 

}

问题可能在于 onViewCreate() 中还没有构建视图,因此不建议在那里设置监听器。

于 2013-02-27T14:13:40.367 回答
2
 lv.setOnItemClickListener(new OnItemClickListener() {

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

我认为这应该有效

于 2013-02-27T14:24:03.110 回答
2

适配器有方法 areAllItemsEnabled(),它可能有用。

公共抽象布尔 areAllItemsEnabled ()

指示是否启用此适配器中的所有项目。如果此方法返回的值随时间变化,不保证会生效。如果为 true,则表示所有项目都是可选择和可点击的(没有分隔符。)

于 2013-03-10T11:42:53.130 回答
1
@Override

public void onListItemClick(ListView l, View v, int position, long id) {
    // TODO Auto-generated method stub
    super.onListItemClick(l, v, position, id);
}
于 2013-02-27T14:21:38.533 回答
0

只需放入android:focusable="false" android:clickable="false"布局。对于所有文本视图、按钮等。问题已解决。

于 2013-12-09T06:17:06.910 回答
0

我有一个类似的问题,我花了很长时间才弄清楚出了什么问题。以前我的片段的 onListItemClick() 打开了新活动,但在返回片段后,onListItemClick() 侦听器不再工作。

@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)
}

这个问题是通过在我的自定义 ArrayAdapter 中创建一个侦听器来解决的。我将此代码放在 getView() 中:

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

我整晚都在解决这个问题(现在是早上 8 点),我想我应该将我的解决方案发布给处于类似位置的其他人:)

于 2017-03-27T07:10:09.590 回答