【问题标题】:how to get a list item position by clicking the button inside it?如何通过单击其中的按钮来获取列表项位置?
【发布时间】:2011-04-10 15:44:23
【问题描述】:

实际上我已经阅读了一些关于此的先前问题......

这是我使用的代码

auto = (ListView)findViewById(R.id.auto);
String[] projection = new String[] {Browser.BookmarkColumns._ID,Browser.BookmarkColumns.TITLE,Browser.BookmarkColumns.URL};

    String[] displayFields = new String[] {Browser.BookmarkColumns.TITLE, Browser.BookmarkColumns.URL};

    int[] displayViews = new int[] { R.id.text1,R.id.text2 };

    Cursor cur = managedQuery(android.provider.Browser.BOOKMARKS_URI,projection, null, null, null);

    //auto.setAdapter(new SimpleCursorAdapter(this, R.layout.mylist, cur,displayFields, displayViews));

    myAdapter apt = new myAdapter(this, R.layout.mylist, cur,displayFields, displayViews);
    auto.setAdapter(apt);

和类 myAdapter

class myAdapter extends SimpleCursorAdapter{

    private Cursor c;
    private Context context;


    public myAdapter(Context context, int layout, Cursor c, String[] from,
            int[] to) {
        super(context, layout, c, from, to);
        // TODO Auto-generated constructor stub
        this.c = c;
        this.context = context;
        AutoList att = new AutoList();
        mListView = att.auto;

    }

    @Override
    public View getView(int pos, View inView, ViewGroup parent) {
           View vix = inView;

           if (vix == null) {
                LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                vix = inflater.inflate(R.layout.mylist, null);
           }
           this.c.moveToPosition(pos);      

           String title = this.c.getString(this.c.getColumnIndex(Browser.BookmarkColumns.TITLE));

           String cont = this.c.getString(this.c.getColumnIndex(Browser.BookmarkColumns.URL));

               TextView text1 = (TextView) vix.findViewById(R.id.text1);
               text1.setText(title);
               TextView text2 = (TextView) vix.findViewById(R.id.text2);
               text2.setText(cont);
               Button butt = (Button) vix.findViewById(R.id.button);
               butt.setOnClickListener(mButt);
               return vix;
    }

    private OnClickListener mButt = new OnClickListener() {
        @Override
        public void onClick(View v) {
        final int position = mListView.getPositionForView((View) v.getParent());
            Log.v("BUTT", "Title clicked, row "+position);
        }
    };

但是,当我点击按钮时,我仍然会收到很多这样的错误:

04-10 22:30:55.152: ERROR/AndroidRuntime(695): FATAL EXCEPTION: main
04-10 22:30:55.152: ERROR/AndroidRuntime(695): java.lang.NullPointerException
04-10 22:30:55.152: ERROR/AndroidRuntime(695):     at             com.auto2.AutoList$myAdapter$1.onClick(AutoList.java:113)
04-10 22:30:55.152: ERROR/AndroidRuntime(695):     at   android.view.View.performClick(View.java:2408)
04-10 22:30:55.152: ERROR/AndroidRuntime(695):     at   android.view.View$PerformClick.run(View.java:8816)
04-10 22:30:55.152: ERROR/AndroidRuntime(695):     at android.os.Handler.handleCallback(Handler.java:587)
04-10 22:30:55.152: ERROR/AndroidRuntime(695):     at   android.os.Handler.dispatchMessage(Handler.java:92)
04-10 22:30:55.152: ERROR/AndroidRuntime(695):     at android.os.Looper.loop(Looper.java:123)
04-10 22:30:55.152: ERROR/AndroidRuntime(695):     at android.app.ActivityThread.main(ActivityThread.java:4627)
04-10 22:30:55.152: ERROR/AndroidRuntime(695):     at java.lang.reflect.Method.invokeNative(Native Method)
04-10 22:30:55.152: ERROR/AndroidRuntime(695):     at java.lang.reflect.Method.invoke(Method.java:521)
04-10 22:30:55.152: ERROR/AndroidRuntime(695):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
04-10 22:30:55.152: ERROR/AndroidRuntime(695):     at   com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
04-10 22:30:55.152: ERROR/AndroidRuntime(695):     at   dalvik.system.NativeStart.main(Native Method)

就是这样! 我希望它不会那么难以弄清楚!

谢谢!

【问题讨论】:

    标签: android listview simplecursoradapter


    【解决方案1】:

    实际上,我使用了相同的方法 - 只是添加了父布局的转换,我得到了没有任何异常的位置

    public void deleteButtonClick(View v) {
            //TODO Remove favorite - DB + file system
            Toast.makeText(this, "Deleting bookmark", Toast.LENGTH_SHORT).show();
            final int position = getListView().getPositionForView((LinearLayout)v.getParent());
            if (position >= 0) {
                Favorite o = (Favorite) this.getListAdapter().getItem(position);
            }
    }
    

    我的列表视图行布局:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res/com.bbox.application"
        android:orientation="vertical" android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <com.markupartist.android.widget.ActionBar
            android:id="@+id/actionbar" app:title="@string/ac_title" style="@style/ActionBar" />
        <ListView android:id="@+id/android:list" android:layout_width="fill_parent"
            android:layout_height="wrap_content" android:layout_weight="5"
            android:background="@drawable/categrory_bckgr" />
        <TextView android:id="@+id/android:empty"
            android:layout_width="fill_parent" android:layout_height="wrap_content"
            android:text="@string/main_no_items" />
    
    </LinearLayout>
    

    希望对你有帮助。

    【讨论】:

      【解决方案2】:

      一个更简单的解决方案可能是当您的 Activity 实现 OnClickListener 并将(转换的)上下文设置为 OnClickListener 到适配器中您想要的任何视图时。对于更健壮的代码,您可以使用 instanceof 进行检查。

      public class MyActivity implements OnClickListener {
      
          // ...
      
      }
      
      public class MyAdapter extends CursorAdapter {
      
          @Override
          public void bindView(View view, Context context, Cursor cursor) {
      
              final TextView tv = (View) view.findViewById(R.id.text1);
      
              setOnClickListener((OnClickListener)context);
      
              tv.setTag(cursor.getPosition());
      
          }
      
      }
      

      为方便起见,您可以将适配器中的项目位置设置为视图的标记。这样您就可以轻松地在适配器中查找整个项目。

      【讨论】:

      • 是的,这可能是最快的方法...标签只会占用一点点内存...不确定在包含许多项目的列表视图中会产生什么样的影响...
      【解决方案3】:

      我们可以通过在adapter的getView方法中实现onClickListener来获取位置。

      适配器:

      public class DetailsListAdapter extends BaseAdapter {
      Context context;
      ArrayList<Profile> data;
      
      public DetailsListAdapter(Context context, ArrayList<Profile> data) {
          this.context = context;
          this.data = data;
      }
      
      @Override
      public int getCount() {
          return data.size();
      }
      
      @Override
      public Object getItem(int position) {
          return data.get(position);
      }
      
      @Override
      public long getItemId(int position) {
          return position;
      }
      
      @Override
      public View getView(final int position, View convertView, ViewGroup parent) {
          ViewHolder viewHolder;
          if (convertView == null) {
              convertView = LayoutInflater.from(context).inflate(R.layout.list_item_logs_details, null);
              viewHolder = new ViewHolder();
              viewHolder.btn = (Button) convertView.findViewById(R.id.log_details_1_a);
              viewHolder.btn.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                          Log.d("statusPosition","position "+position);
                  }
              });
              convertView.setTag(viewHolder);
          } else {
              viewHolder = (ViewHolder) convertView.getTag();
          }
      
          return convertView;
      }
      
      public static class ViewHolder {
          TextView tv2, tv3, tv3a, tv4, tv4a;
          Button btn;
      }
      }
      

      【讨论】:

        【解决方案4】:

        带有可点击按钮的ListView!!!

        嗯....,这是解决我的问题 SO FAR 的粗略方法....

        item.xml:

        <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                    android:layout_width="fill_parent"
                    android:orientation="horizontal"
                    android:layout_height="wrap_content">
        <TextView android:id="@+id/showTv"
              android:layout_alignParentLeft="true"
              android:gravity="center_vertical"
              android:textSize="24dip"
              android:layout_height="wrap_content"
              android:layout_width="wrap_content" /> 
         <RelativeLayout android:id="@+id/jjjj"
                         android:layout_alignParentRight="true"
                         android:layout_height="wrap_content"
                         android:layout_width="wrap_content">        
              <Button android:id="@+id/gointoBt"
                       android:focusable="false"
                       android:layout_alignParentRight="true"
                       android:text="abc"
                       android:layout_height="wrap_content"
                       android:layout_width="wrap_content"/> 
              <Button android:id="@+id/chooseBt"
                      android:layout_toLeftOf="@id/gointoBt"
                      android:layout_marginRight="10dip"
                      android:text="text"
                      android:focusable="false"
                      android:layout_height="wrap_content"
                      android:layout_width="wrap_content"/>
          </RelativeLayout> 
        

        MySimpleAdapter:

        import ........;
        
        public class MySimpleAdapter extends SimpleAdapter {
        
        private final Context context;
        private List<Map<String, Object>> data;
        private int resource;
        private String[] from;
        private int[] to;
        
        public MySimpleAdapter(Context context,List<? extends Map<String, ?>> data, int resource, String[] from,
        int[] to) {
           super(context, data, resource, from, to);
           this.context=context;
           this.data=(List<Map<String, Object>>) data;
           this.resource=resource;
           this.from=from;
           this.to=to;
        }
        
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
        
           LayoutInflater inflater = ((Activity)context).getLayoutInflater();
           View rowView = inflater.inflate(resource, null, true); 
           Map<String, Object> medMap=data.get(position);
           final TextView[] showTv=new TextView[from.length]; 
        
           for (int i = 0; i < from.length; i++) { 
            showTv[i]=(TextView)rowView.findViewById(to[i]);
            showTv[i].setText(""+medMap.get(from[i]));
           }
        Button btn=(Button)rowView.findViewById(R.id.gointoBt);
           Button.OnClickListener mOkOnClickListener = new Button.OnClickListener()
              {
                 public void onClick(View v) {
                 Log.v("ttttttt", ""+showTv[0].getText());
                 Toast.makeText(context,""+showTv[0].getText(), Toast.LENGTH_LONG).show();
                 }
             };
         btn.setOnClickListener(mOkOnClickListener); 
        
             Button btn2=(Button)rowView.findViewById(R.id.chooseBt);
           Button.OnClickListener mOkOnClickListener2 = new Button.OnClickListener()
              {
                  public void onClick(View v) {
                  Log.v("hhhhhhh", ""+showTv[0].getText());
                  Toast.makeText(context,"abc"+showTv[0].getText(), Toast.LENGTH_LONG).show();
                  }
              };
           btn2.setOnClickListener(mOkOnClickListener2);     
           return rowView; 
        }
        }
        

        活动:

        import .......;
        
        public class   ActivityMain extends Activity {
        
        ListView listview;
        List<Map<String,Object>> data;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setTitle("My work");
           prepareData(); 
           listview =new ListView(this);
           MySimpleAdapter adapter=new MySimpleAdapter(this,data,R.layout.item,new String[]      {"uu"},new int[]{R.id.showTv});
        
           listview.setAdapter(adapter);                            
             setContentView(listview);
        
        }
        private void prepareData(){
           data=new ArrayList<Map<String,Object>>();
           Map<String,Object> item;
           item=new HashMap<String,Object>();
           item.put("uu", "hello");
           data.add(item);
           item=new HashMap<String,Object>();
           item.put("uu", "myyou");
           data.add(item);
           item=new HashMap<String,Object>();
           item.put("uu", "piero");
           data.add(item);
        }
        
        }
        

        感谢这位好心人提供这个令人敬畏但最强大的教程.... 这里的任何人都不能给菜鸟....

        【讨论】:

          【解决方案5】:

          我认为还有一种最好的方法。您可以使用按钮添加一个标签作为位置 (button.setTag()) 方法,每当用户单击按钮时,只需获取此按钮的标签。它会更容易。

          感谢和问候 拉胡尔

          【讨论】:

            【解决方案6】:

            非常简单。在您的 Adapter 类 getView 方法中将 int position 更改为 final int position

            public View getView(final int position, View convertView, ViewGroup parent) {
            
            LayoutInflater inflater = (LayoutInflater) context
                            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    View row = inflater.inflate(yourcustomizeditemview.xml, parent,
                            false);
            Button btn= (Button) row.findViewById(R.id.btn);
            btn.setOnClickListener(new OnClickListener() {
            
                        @Override
                        public void onClick(View v) {
                            // TODO Auto-generated method stub
            
                            Toast.makeText(context, " "+position, Toast.LENGTH_SHORT).show();
            
                        }
                    });
            return row;
                }
            

            现在在Button 点击Toast 显示Button 所在项目的位置。

            【讨论】:

              【解决方案7】:

              onClick() 中,mListView 似乎为空。有可能

              auto = (ListView)findViewById(R.id.auto);
              

              返回 null,因为在当前布局中找不到 R.id.auto 的视图。我会在该行之后放置一个调试器断点并查看。

              【讨论】:

              • 在本教程中stackoverflow.com/questions/1709166/… 他们说我们需要为将要使用的关联数据添加 setTag 和 getTag。你能告诉我如何实现它吗?
              • 这应该是在您的 ListView 标签中添加一个android:id=@+id/auto 属性的问题。
              • 对不起,我是新手,所以你的意思是我需要删除 listview id 标签吗?或者我还有什么需要做的吗?
              【解决方案8】:

              你会执行这个

              btnNxt = (Button) findViewById(R.id.btnNext);
               btnNxt.setOnClickListener(new OnClickListener() {
               @Override
               public void onClick(View arg0) {
                //Here I need to get that position
              });
              

              在 getView 方法中?如果是这样,那就很容易了

               btnNxt = (Button) findViewById(R.id.btnNext);
               btnNxt.setTag(position);
               btnNxt.setOnClickListener(new OnClickListener() {
               @Override
               public void onClick(View arg0) {
                int position=(Integer)arg0.getTag();
              });
              

              来自:https://stackoverflow.com/a/20542034

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2013-12-30
                • 2013-06-20
                • 1970-01-01
                • 2021-11-08
                • 1970-01-01
                • 1970-01-01
                • 2020-06-08
                相关资源
                最近更新 更多