【问题标题】:Onclicklistner not working in fragment listviewOnclicklistener 在片段列表视图中不起作用
【发布时间】:2013-02-13 08:54:10
【问题描述】:

我在 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>

【问题讨论】:

  • 您是否尝试在 onViewCreated(View view, Bundle savedInstanceState) 中声明监听器?而不是在 onCreateView() 内部。它不应该存在于 onViewCreate() 方法中。

标签: android listview fragment android-listfragment custom-adapter


【解决方案1】:

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

【讨论】:

  • 谢谢!经过一个小时的调试,这对我有所帮助......!
  • 这对我也有用!我将代码 android:focusable="false" 用于与我的片段类关联的 XML 中的所有 ButtonsTextViews。跨度>
【解决方案2】:

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

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

     row.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

        }
    });

【讨论】:

    【解决方案3】:

    根据 Android API 文档:

    ListFragment 有一个由单个列表视图组成的默认布局。 但是,如果您愿意,可以通过以下方式自定义片段布局 从 onCreateView(LayoutInflater, 视图组,捆绑包)。 为此,您的视图层次结构必须包含 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;
        }
    }
    

    【讨论】:

      【解决方案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;
      }
      

      【讨论】:

      • @jeevamuthu 带有android:id="@+id/fav"android:id="@+id/tips" 的按钮在哪里
      • 现在查看 listview_layout.xml。我也需要点击列表视图和列表视图行中的按钮
      • @jeevamuthu 我已经编辑了答案并修复了您的 getView 函数。 cmets 应该让您更好地了解 Holder,当然还有点击监听器
      • 感谢响应我需要在单击该列表视图行时显示另一个片段。我能做些什么呢?
      【解决方案5】:

      将以下代码放入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()中还没有构造视图,所以不建议在那里设置监听器。

      【讨论】:

      • 感谢您的回复。我已经实现了这个方法,但没有用。请提供任何样品。
      • 吐司没有出现?
      • yes.toast 没有出现。我已经将 CustomAdapter 用于列表视图。
      • 向我们展示您的“MyCustomAdapter”类。
      • 请参阅 MyCustomAdapter 类。
      【解决方案6】:
       lv.setOnItemClickListener(new OnItemClickListener() {
      
              @Override
              public void onItemClick(AdapterView<?> parent, View view,
                      int position, long id) {
                      //your code
              }
         });
      

      我认为这应该可行

      【讨论】:

        【解决方案7】:

        Adapter有方法areAllItemsEnabled(),可能有用。

        公共抽象布尔 areAllItemsEnabled ()

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

        【讨论】:

          【解决方案8】:
          @Override
          
          public void onListItemClick(ListView l, View v, int position, long id) {
              // TODO Auto-generated method stub
              super.onListItemClick(l, v, position, id);
          }
          

          【讨论】:

            【解决方案9】:

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

            【讨论】:

              【解决方案10】:

              我遇到了类似的问题,我花了很长时间才弄清楚出了什么问题。 以前我的片段的 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 点),我想我应该将我的解决方案发布给处于类似位置的其他人 :)

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2023-03-30
                相关资源
                最近更新 更多