Android的SimpleAdapter错误的数据项被与列表行关联 [英] Android SimpleAdapter wrong data-item gets associated with a list row

查看:162
本文介绍了Android的SimpleAdapter错误的数据项被与列表行关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有关联的自定义SimpleAdapter列表视图。我做了定制SimpleAdapter因为我想不同的事件处理程序所包含的TextView和ImageView的比列表项部件的其余部分关联。所以,基本上我有两个不同的事件处理程序列表项两部分组成。

I have a listview with custom SimpleAdapter associated. I made the custom SimpleAdapter because I want to associate a different event handler with the contained textview and the imageview than the rest of the list-item widgets. So, basically I have two different event handlers for two parts of a list-item.

我SimpleAdapter定制是:

My SimpleAdapter customization is:

class ClickableButtonListAdapter extends SimpleAdapter {

    private static class ViewHolder {
        TextView text;
        ImageView image;
    }

    public ClickableButtonListAdapter(Context context,
        List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
        super(context, data, resource, from, to);
    }

    @SuppressWarnings("unchecked")
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final View view = super.getView(position, convertView, parent);
        ViewHolder holder = (ViewHolder) view.getTag();
        if(holder == null) {
            holder = new ViewHolder();
            holder.text = (TextView) view.findViewById(R.id.comments);
            holder.image = (ImageView) view.findViewById(R.id.arrow);
            view.setTag(holder);
            final Context context = view.getContext();
            final HashMap<String, String> article = (HashMap<String,String>) getItem(position);
            OnClickListener listener = new OnClickListener() {
                @Override
                public void onClick(View view) {
                    String item_id = article.get("item_id");
                    Intent intent = new Intent(context, HNewsCommentsActivity.class);
                    intent.putExtra("item_id", item_id);
                    context.startActivity(intent);
                }
            };
            holder.text.setOnClickListener(listener);
            holder.image.setOnClickListener(listener);
        }
        return view;
    }
}

后来,在我的活动的onCreate,我联想我的自定义SimpleAdapter是这样的:

Later, in my activity onCreate, I associate my custom SimpleAdapter like this:

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        try {
            final ArrayList<HashMap<String, String>> articles = getHNewsFeed();
            final SimpleAdapter adapter = new ClickableButtonListAdapter(this,
                    articles, R.layout.article,
                    new String[] {"title", "urlShort", "score", "comments", "item_id"},
                    new int[] {R.id.title, R.id.url, R.id.score, R.id.comments, R.id.item_id}
                    );
            final ListView l = (ListView) findViewById(android.R.id.list);
            l.setAdapter(adapter);
            l.setOnItemClickListener( new OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                    final HashMap<String, String> article = articles.get(position);
                    String url = article.get("url");
                    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                    startActivity(intent);
                }
            });
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
            Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

我的问题是,这些与TextView的含有和ImageView的(我在自定义SimpleAdapter的getView初始化)相关联的事件处理程序似乎得到在单击一个不同的文章的错误数据源项,并显示数据。该ListView项单击处理程序,但是,得到正确的数据源项。有人可以帮我说明一下为什么这个事件处理我一个TextView,并在自定义的getView一个ImageView的关联SimpleAdapter不能正常工作?我的理解是'的getItem(位置)的SimpleAdapter的方法应该返回正确的数据源项。但由于某些原因,它不会出现这样做。

My problem is these the event handler associated with the contained textview and imageview (which I initialize in getView of the custom SimpleAdapter) seem to get a wrong data-source item and shows data of a different article upon clicking. The listview item click handler, however, gets the correct data source item. Can somebody help me in pointing out why the event handler I associate with a textview and an imageview in getView of the custom SimpleAdapter does not work correctly? My understanding is 'getItem(position)' method of the SimpleAdapter should be returning the correct data source item. But for some reason, it does not appear to do so.

推荐答案

有在你的逻辑是错误的。适配器的getView方法被调用了很多次,一个视图可以显示不同时期不同的项目。

There is a mistake in your logic. Adapter's getView method is called a lot of times and one View can show different items in different periods of time.

因此​​,它是如何工作的:

So how it works:

在ListView控件希望它调用从适配器类方法getView项(如果这种观点应该显示用户或只是用来计算查看项目的大小并不重要)。 ListView控件传递convertView参数 - 这是老认为,这种适配器前回来一段时间,现在没有必要。它是确定重用它,而不是再膨胀(超级方法是这样的)。这里是你的code问题。如果旧的观点传递给你的getView方法,它已经有标签的对象。而你(持有者== NULL)==假。所以,查看重新presents一文打开一个其他。

When ListView wants an item it calls method getView from Adapter class (doesn't matter if this view should be shown to user or used just to calculate view item's size). ListView passes convertView parameter - this is old view that this adapter returned some time ago and now not needed. It is ok to reuse it and not inflate again (super method works like this). And here is your code problem. If old view is passed to your getView method, it already has tag object. And your (holder == null) == false. And so view that represents one article opens an other.

试着改变你的逻辑来修正这个错误。最好的办法是创建持有人只有一个,每次的时间和设置视图的听众。

Try to change you logic to fix this mistake. The best way is to create holder only one time and set view listeners every time.

希望这会有所帮助。

编辑。
这里是解决问题的方法有两种。

EDIT. Here is two ways to fix problem.

@SuppressWarnings("unchecked")
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    final View view = super.getView(position, convertView, parent);
    ViewHolder holder = (ViewHolder) view.getTag();
    if(holder == null) {
        holder = new ViewHolder();
        holder.text = (TextView) view.findViewById(R.id.comments);
        holder.image = (ImageView) view.findViewById(R.id.arrow);
        view.setTag(holder);
    }

    final Context context = view.getContext();
    final HashMap<String, String> article = (HashMap<String,String>) getItem(position);
    OnClickListener listener = new OnClickListener() {
        @Override
        public void onClick(View view) {
            String item_id = article.get("item_id");
            Intent intent = new Intent(context, HNewsCommentsActivity.class);
            intent.putExtra("item_id", item_id);
            context.startActivity(intent);
        }
    };
    holder.text.setOnClickListener(listener);
    holder.image.setOnClickListener(listener);

    return view;
}

第二,我更爱。感谢维奈小号谢诺伊这个版本。

The second, that I love more. Thanks Vinay S Shenoy for this version.

@SuppressWarnings("unchecked")
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    final HashMap<String, String> article = (HashMap<String,String>) getItem(position);

    final View view = super.getView(position, convertView, parent);
    ViewHolder holder = (ViewHolder) view.getTag();
    if(holder == null) {
        holder = new ViewHolder();
        holder.text = (TextView) view.findViewById(R.id.comments);
        holder.image = (ImageView) view.findViewById(R.id.arrow);
        view.setTag(holder);
        final Context context = view.getContext();
        OnClickListener listener = new OnClickListener() {
            @Override
            public void onClick(View view) {
                String item_id = view.getTag();
                //String item_id = article.get("item_id");
                Intent intent = new Intent(context, HNewsCommentsActivity.class);
                intent.putExtra("item_id", item_id);
                context.startActivity(intent);
            }
        };
        holder.text.setOnClickListener(listener);
        holder.image.setOnClickListener(listener);
    }

    holder.text.setTag(article.get("item_id"));
    holder.image.setTag(article.get("item_id"));

    return view;
}

这篇关于Android的SimpleAdapter错误的数据项被与列表行关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆