【问题标题】:Android ListView Adapter OnClickListener issueAndroid ListView 适配器 OnClickListener 问题
【发布时间】:2011-05-26 13:23:11
【问题描述】:

我为每个视图创建了一个带有自定义布局的 ListView。我在自定义布局中的 TextView 项目的列表视图适配器中有几个 onClickListeners。 onClickListeners 在列表视图适配器中工作,我可以获得视图的位置,但是当我尝试在 onClickListeners 内调用我的活动中的方法时,我得到“无法对非静态方法进行静态引用方法”错误。所以我开始将事物转换为静态,这使事情按预期工作,但我相信你们都知道这是一个很大的错误,它终于赶上了我。

如何在不使方法静态的情况下访问主要活动中的方法?我是新手,所以请原谅我的菜鸟问题。谢谢

部分代码清单...

public class main extends Activity {
    private ArrayList<DataItem> dataItems;
    private DataItemAdapter aa;
    private ListView dataListView;  

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        dataListView = (ListView)findViewById(R.id.dataListView);     
        dataItems = new ArrayList<DataItem>();
        int resID = R.layout.dataitem;
        aa = new DataItemAdapter(this, resID, dataItems);
        dataListView.setAdapter(aa);
        dataListView.setItemsCanFocus(true);

    populateArray();
}

public void populateArray() {
    DataItem newItem = new DataItem(
            "2008","Ferrari","F430","Red","ASX772"
        );
    dataItems.add(0, newItem);
    newItem = new DataItem(
            "2008","Ferrari","F430","Black","TZB123"
        );
    dataItems.add(0, newItem);
    newItem = new DataItem(
            "2009","Ferrari","F430","Red","MIDAS"
        );
    dataItems.add(0, newItem);      

    aa.notifyDataSetChanged();
}

public static void modelInfo(int pos) {
    Log.i("modelInfo", "=" + pos);
}

public static void makeInfo(int pos) {
    Log.i("makeInfo", "=" + pos);
}

public static void assetInfo(int pos) {
    Log.i("assetInfo", "=" + pos);
}

}


public class DataItemAdapter extends ArrayAdapter<DataItem> {
    private Activity activity;
    private int resource;
    private static LayoutInflater inflater=null;

    public DataItemAdapter(Activity _activity,int _resource,List<DataItem> _items) {
        super(_activity, _resource, _items);
        inflater = (LayoutInflater)_activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        resource = _resource;
        activity = _activity;
    }

public static class ViewHolder {
    TextView carYear;
    TextView carMake;
    TextView carModel;
    TextView carColor;
    TextView assetTag;
   }

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View vi=convertView;
    ViewHolder holder;
    if (convertView == null) {
        vi = inflater.inflate(resource, null);
        holder=new ViewHolder();
        holder.carYear = (TextView)vi.findViewById(R.id.carYear);
        holder.carMake = (TextView)vi.findViewById(R.id.carMake);
        holder.carModel = (TextView)vi.findViewById(R.id.carModel);
        holder.carColor = (TextView)vi.findViewById(R.id.carColor);
        holder.assetTag = (TextView)vi.findViewById(R.id.assetTag);
        vi.setTag(holder);
    } else {
        holder=(ViewHolder)vi.getTag();
    }

    DataItem item = getItem(position);  

    holder.carYear.setText(item.getCarYear());
    holder.carMake.setText(item.getCarMake());
    holder.carModel.setText(item.getCarModel());
    holder.carColor.setText(item.getCarColor());
    holder.assetTag.setText(item.getAssetTag());

    holder.carYear.setTag(position);
    holder.assetTag.setTag(position);

    final OnClickListener makeListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            LinearLayout ll = (LinearLayout)v.getParent();
            TextView tv = (TextView)ll.getChildAt(0);
            Integer pos = (Integer) tv.getTag();
            main.makeInfo(pos);
        }
    };
    holder.carMake.setOnClickListener(makeListener);

    final OnClickListener modelListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            LinearLayout ll = (LinearLayout)v.getParent();
            TextView tv = (TextView)ll.getChildAt(0);
            Integer pos = (Integer) tv.getTag();
            main.modelInfo(pos);

        }
   };        

    holder.carModel.setOnClickListener(modelListener);

    final OnClickListener assetListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            LinearLayout ll = (LinearLayout)v.getParent();
            TextView tv = (TextView)ll.getChildAt(0);
            Integer pos = (Integer) tv.getTag();
            main.assetInfo(pos);
        }
    };
    holder.assetTag.setOnClickListener(assetListener);        

    return vi;
}

【问题讨论】:

    标签: android


    【解决方案1】:

    为什么您不在 Activity 中将 onItemClickListener 附加到 ListView,而不是从 ListView 中的每个内部视图执行 ItemClick

            dataListView = (ListView)findViewById(R.id.dataListView);     
            dataItems = new ArrayList<DataItem>();
            int resID = R.layout.dataitem;
            aa = new DataItemAdapter(this, resID, dataItems);
            dataListView.setAdapter(aa);
            //attach a listener to the list view
            dataListView.setOnItemClickListener (listener);
    
            dataListView.setItemsCanFocus(true);
    

    在 onItemClick 方法的侦听器中,您可以访问活动方法。

    编辑 1: OnItemClickListener 给你以下参数,AdapterView parent,View view,int position,long

    您的个人 TextView 是 view 参数的子项,您可以通过获取 childAt... 来访问它,如下所示:

    OnItemClickListener listener = new OnItemClickListener (){
    
      @Override
      onItemClick(AdapterView<?> parent, View view, int position, long id){
          ((TextView)view.findViewById(R.id.yourTextViewId)).getText();
          //or do your stuff
      }
    
    }
    

    编辑 2:

    你的主要活动,记住,按照惯例,所有的类名都是大写的,所以主类必须是主类

    public class Main extends Activity {
        private ArrayList<DataItem> dataItems;
        private DataItemAdapter aa;
        private ListView dataListView;  
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            dataListView = (ListView)findViewById(R.id.dataListView);     
            dataItems = new ArrayList<DataItem>();
            int resID = R.layout.dataitem;
            aa = new DataItemAdapter(this, resID, dataItems);
            dataListView.setAdapter(aa);
            dataListView.setItemsCanFocus(true);
    
        populateArray();
    }
    
    public void populateArray() {
        DataItem newItem = new DataItem(
                "2008","Ferrari","F430","Red","ASX772"
            );
        dataItems.add(0, newItem);
        newItem = new DataItem(
                "2008","Ferrari","F430","Black","TZB123"
            );
        dataItems.add(0, newItem);
        newItem = new DataItem(
                "2009","Ferrari","F430","Red","MIDAS"
            );
        dataItems.add(0, newItem);      
    
        aa.notifyDataSetChanged();
    }
    
    public void modelInfo(int pos) {
        Log.i("modelInfo", "=" + pos);
    }
    
    public void makeInfo(int pos) {
        Log.i("makeInfo", "=" + pos);
    }
    
    public void assetInfo(int pos) {
        Log.i("assetInfo", "=" + pos);
    }
    }
    

    现在,你的适配器

    public class DataItemAdapter extends ArrayAdapter<DataItem> {
        private Activity activity;
        private int resource;
        private LayoutInflater inflater=null;
    
        public DataItemAdapter(Activity _activity,int _resource,List<DataItem> _items) {
            super(_activity, _resource, _items);
            inflater = (LayoutInflater)_activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            //i always do this way, but i dont think this is the error
            //inflater = LayoutInflater.from(_activity.getBaseContext());
            resource = _resource;
            activity = _activity;
        }
    
    public static class ViewHolder {
        TextView carYear;
        TextView carMake;
        TextView carModel;
        TextView carColor;
        TextView assetTag;
       }
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View vi=convertView;
        ViewHolder holder;
        if (convertView == null) {
            vi = inflater.inflate(resource, null);
            holder=new ViewHolder();
            holder.carYear = (TextView)vi.findViewById(R.id.carYear);
            holder.carMake = (TextView)vi.findViewById(R.id.carMake);
            holder.carModel = (TextView)vi.findViewById(R.id.carModel);
            holder.carColor = (TextView)vi.findViewById(R.id.carColor);
            holder.assetTag = (TextView)vi.findViewById(R.id.assetTag);
            vi.setTag(holder);
        } else {
            holder=(ViewHolder)vi.getTag();
        }
    
        DataItem item = getItem(position);  
    
        holder.carYear.setText(item.getCarYear());
        holder.carMake.setText(item.getCarMake());
        holder.carModel.setText(item.getCarModel());
        holder.carColor.setText(item.getCarColor());
        holder.assetTag.setText(item.getAssetTag());
    
        holder.carYear.setTag(position);
        holder.assetTag.setTag(position);
    
        final OnClickListener makeListener = new OnClickListener() {
            @Override
            public void onClick(View v) {
                LinearLayout ll = (LinearLayout)v.getParent();
                TextView tv = (TextView)ll.getChildAt(0);
                Integer pos = (Integer) tv.getTag();
                //main.makeInfo(pos);
                ((Main)activity).makeInfo(pos);
            }
        };
        holder.carMake.setOnClickListener(makeListener);
    
        final OnClickListener modelListener = new OnClickListener() {
            @Override
            public void onClick(View v) {
                LinearLayout ll = (LinearLayout)v.getParent();
                TextView tv = (TextView)ll.getChildAt(0);
                Integer pos = (Integer) tv.getTag();
                //main.modelInfo(pos);
                ((Main)activity).modelInfo(pos);
            }
       };        
    
        holder.carModel.setOnClickListener(modelListener);
    
        final OnClickListener assetListener = new OnClickListener() {
            @Override
            public void onClick(View v) {
                LinearLayout ll = (LinearLayout)v.getParent();
                TextView tv = (TextView)ll.getChildAt(0);
                Integer pos = (Integer) tv.getTag();
                //main.assetInfo(pos);
                ((Main)activity).assetInfo(pos);
            }
        };
        holder.assetTag.setOnClickListener(assetListener);        
    
        return vi;
    }
    

    希望它有效:)

    【讨论】:

    • 感谢您的回复。 onItemClickListener 是否允许指示在自定义布局 VICE 中单击了哪些单个 TextView 项,仅指单击的单个视图(位置)?如何?这可能是我缺少的信息。
    • 再次感谢。我了解您的示例,但我不需要单击的值,我需要知道单击了哪个 TextView。即 TextView1、TextView2、TextView3、TextView4。我一直在玩它,但我不知道如何将 R.id.myTextViewId 与点击的内容匹配。
    • 好的,我把这个值作为例子,因为你在那里得到了 TextView 实例,你可以用它做你想做的事:)
    • 我已经旋转了一个小时,但我仍然无法弄清楚如何确定自定义布局中的四个 TextView 中的哪一个被单击。我可以用 TextViews 做事,但仅此而已。 ftw 哈哈
    • 您是构建您的 ListView 还是从 xml 布局膨胀?你可以弄清楚 TextView id、TextView 标签、TextView 内容、适配器中的位置等点击的 TextView 是什么。也许我不明白你的用例。也许您可以编辑您的帖子并添加一些额外的数据,例如适配器中的 getView 方法:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 2018-04-18
    相关资源
    最近更新 更多