面对关键问题:使用ViewHolder模式里切换列表视图图像源 [英] Facing critical issue: Toggle image source inside Listview using ViewHolder Pattern

查看:181
本文介绍了面对关键问题:使用ViewHolder模式里切换列表视图图像源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的ListView的列表项我有一个多控制和其中一个是ImageView的。我的目的就是用户时图片的点击,源应改为别的东西。我采取ViewHolder模式,而现在我能够切换上单击源。我现在的问题是,当我向下滚动新的观点越来越创建(再使用),当我试图再次走高,其中i切换形象再次得到使用默认图像源创建为我的数据源LIST一直保持相同的列表项。请帮助。

 私有类ViewHolder:的java.lang.Object
    {
        //活动方面;
        公共MyTextView HadithBook;
        公共MyTextView HadithChapter;
        公共MyTextView HadithText;
        公共ImageView的FavButton;
        公共ImageView的ShareButton;
        公共事件处理程序处理程序;
        公共MyTextView RowId的;
        公共MyTextView IsFavorite;
    }
        公众覆盖查看GetView(INT位置,查看convertView,父母的ViewGroup)
    {
        ViewHolder支架=无效;
        如果(convertView == NULL)
        {
            convertView = context.LayoutInflater.Inflate(Resource.Layout.HadithListViewItem,NULL);
            持有人=新ViewHolder();
            holder.HadithBook = convertView.FindViewById< MyTextView> (Resource.Id.HadithBook);
            holder.HadithChapter = convertView.FindViewById< MyTextView> (Resource.Id.HadithChapter);
            holder.HadithText = convertView.FindViewById< MyTextView> (Resource.Id.HadithText);
            holder.FavButton = convertView.FindViewById< ImageView的> (Resource.Id.favButton);
            holder.ShareButton = convertView.FindViewById< ImageView的> (Resource.Id.ShareButton);
            holder.IsFavorite = convertView.FindViewById< MyTextView> (Resource.Id.IsFavorite);
            holder.RowId = convertView.FindViewById< MyTextView> (Resource.Id.RowId);            holder.Handler =(S,E)=> FavoriteHandler(S,E,持有人);            convertView.Tag =持有人;
        }        如果(持有者== NULL)
        {
            支架=(ViewHolder)convertView.Tag;            holder.FavButton.Click - = holder.Handler;
        }        VAR项目=项目[位置]        holder.HadithBook.Text = item.BookName;
        holder.HadithChapter.Text = item.ChapterName + - + item.HadithID;        如果(string.IsNullOrEmpty(关键字)及!string.IsNullOrWhiteSpace(关键字)){
            holder.HadithText.TextFormatted =(Html.FromHtml(ReplaceEx((item.HadithText)的ToString(),关键字&下;字体颜色='#ff9000'>&所述b取代;+关键字+&下; / B个;&所述; /字体>中)));
        }其他{
            holder.HadithText.TextFormatted = Html.FromHtml(item.HadithText);
        }
        如果(holder.FavButton.Tag.Equals(0))
        {
            holder.FavButton.Tag = 0;
            holder.FavButton.SetImageResource(Resource.Drawable.ic_action_not_important);        }其他
        {
            holder.FavButton.Tag = 1;
            holder.FavButton.SetImageResource(Resource.Drawable.ic_action_important);
        }        holder.FavButton.Click + = holder.Handler;
        convertView.SetOnClickListener(NULL);        返回convertView;
        }
        无效FavoriteHandler(对象发件人,EventArgs的,ViewHolder持有人)
    {
        数据库DB =新的数据库();
        如果(holder.FavButton.Tag.Equals(0)){
            holder.FavButton.SetImageResource(Resource.Drawable.ic_action_important);
            holder.FavButton.Tag = 1;
            db.InsertQuery(插入到最喜欢的VALUES('+ holder.RowId +'););        }否则如果(holder.FavButton.Tag.Equals(1)){
            holder.FavButton.SetImageResource(Resource.Drawable.ic_action_not_important);
            holder.FavButton.Tag = 0;
            db.InsertQuery(从最爱删除其中id ='+ holder.RowId +;);
        }
        DB = NULL;    }


解决方案

这是一个陷阱几乎每个人都属于学习如何实现适配器时进入。

的问题是,要在所独有的位置viewholder存储数据。举例来说,你是从holder.FavButton.Tag其值设置之前,阅读,因此你的当前code预计,标签保留的数据给你。

当你通过滚动列表视图,视图回收,这样的话你是从另一个位置读取数据。您可以在视图中不持有缓存与位置相关的数据。相反,它用来保存通用于所有职位的布局元素(即认为是covertable,故名在getView方法convertView)。你必须通过其他途径来缓存数据,例如,通过位置缓存数据是一个HashMap。

Inside my Listview's ListItem i have a multiple controls and one among them is imageview. My purpose is that user when clicks on that image, source should change to something else. I am implementing ViewHolder Pattern, and right now i am able to toggle the source on click. My current problem is that when i scroll down new views are getting created(re-used), and when i try to move Up again the listitem where i toggled the image are again getting created with default image source as my datasource LIST has remained same. Kindly help.

        private class ViewHolder : Java.Lang.Object
    {
        //Activity context;
        public MyTextView HadithBook;
        public MyTextView HadithChapter;
        public MyTextView HadithText;
        public ImageView FavButton;
        public ImageView ShareButton;
        public EventHandler Handler;
        public MyTextView RowId;
        public MyTextView IsFavorite;
    }


        public override View GetView (int position, View convertView, ViewGroup parent)
    {


        ViewHolder holder = null;
        if (convertView == null) 
        {
            convertView = context.LayoutInflater.Inflate (Resource.Layout.HadithListViewItem, null);
            holder = new ViewHolder ();
            holder.HadithBook = convertView.FindViewById<MyTextView> (Resource.Id.HadithBook);
            holder.HadithChapter = convertView.FindViewById<MyTextView> (Resource.Id.HadithChapter);
            holder.HadithText = convertView.FindViewById<MyTextView> (Resource.Id.HadithText);
            holder.FavButton = convertView.FindViewById<ImageView> (Resource.Id.favButton);
            holder.ShareButton = convertView.FindViewById<ImageView> (Resource.Id.ShareButton);
            holder.IsFavorite = convertView.FindViewById<MyTextView> (Resource.Id.IsFavorite);
            holder.RowId = convertView.FindViewById<MyTextView> (Resource.Id.RowId);

            holder.Handler = (s, e) => FavoriteHandler (s, e, holder);

            convertView.Tag = holder;
        }

        if (holder == null) 
        {
            holder = (ViewHolder)convertView.Tag;

            holder.FavButton.Click -= holder.Handler;
        }

        var item = items[position];

        holder.HadithBook.Text = item.BookName;
        holder.HadithChapter.Text = item.ChapterName + " - " + item.HadithID;

        if (!string.IsNullOrEmpty (keyword) & !string.IsNullOrWhiteSpace (keyword)) {
            holder.HadithText.TextFormatted = (Html.FromHtml (ReplaceEx ((item.HadithText).ToString (), keyword, "<font color='#ff9000'><b>" + keyword + "</b></font>")));
        } else {
            holder.HadithText.TextFormatted =Html.FromHtml(item.HadithText);
        }






        if (holder.FavButton.Tag.Equals(0)) 
        {
            holder.FavButton.Tag = 0;
            holder.FavButton.SetImageResource (Resource.Drawable.ic_action_not_important);

        } else 
        {
            holder.FavButton.Tag = 1;
            holder.FavButton.SetImageResource (Resource.Drawable.ic_action_important);
        }

        holder.FavButton.Click += holder.Handler;
        convertView.SetOnClickListener (null);

        return convertView;
        }


        void FavoriteHandler (object sender, EventArgs e, ViewHolder holder)
    {
        Database db = new Database ();
        if (holder.FavButton.Tag.Equals (0)) {
            holder.FavButton.SetImageResource (Resource.Drawable.ic_action_important);
            holder.FavButton.Tag = 1;
            db.InsertQuery ("insert into favorite values ('" + holder.RowId + "');");

        } else if (holder.FavButton.Tag.Equals (1)) {
            holder.FavButton.SetImageResource (Resource.Drawable.ic_action_not_important);
            holder.FavButton.Tag = 0;
            db.InsertQuery ("Delete from favorite where id ='" + holder.RowId + "';");
        }
        db = null;

    }

解决方案

This is a trap nearly everyone falls into when learning how to implement adapters.

The problem is that you are storing data in the viewholder that is unique to the position. For instance, you are reading from holder.FavButton.Tag before setting it with values, thus your current code expects that tag to retain data for you.

As you scroll through the listview, the views are recycled, and thus you are reading data from another position. You cannot cache position-dependent-data in the view holder. Instead its used to hold layout elements which are common to all positions (i.e. the view is covertable, hence the name "convertView" in the getView method). You'll have to cache that data by other means, like a hashmap that caches your data by position.

这篇关于面对关键问题:使用ViewHolder模式里切换列表视图图像源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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