【问题标题】:Android Palette working only on some of RecyclerView itemsAndroid Palette 仅适用于某些 RecyclerView 项目
【发布时间】:2016-06-14 12:20:29
【问题描述】:

我正在尝试为 RecyclerView 中的每个 CardView 生成一个调色板,并根据生成的调色板为卡片着色。
然而,由于一些奇怪的原因,只有 RecyclerView 的最后两个 CardView 被着色了。

这是我的代码(它在 C# 中,使用 Xamarin,但几乎与 Java 代码相同):

回收器适配器:

    public class RecyclerAdapter : RecyclerView.Adapter, Palette.IPaletteAsyncListener
    {
        private List<Book> mBooks;
        private RecyclerView mRecyclerView;
        private Context mContext;
        private int mCurrentPosition = -1;
        private bool isPaletteGenerated = false;
        MyView myHolder;
        public RecyclerAdapter(List<Book> books, RecyclerView recyclerView, Context context)
        {
            mBooks = books;
            mRecyclerView = recyclerView;
            mContext = context;
        }

        public class MyView : RecyclerView.ViewHolder
        {
            public View mMainView { get; set; }
            public TextView mTitle { get; set; }
            public ImageView mCoverImage { get; set; }
            public int mCoverImageResourceID { get; set; }
            public CardView mCard { get; set; }

            public MyView(View view) : base(view)
            {
                mMainView = view;
            }
        }

        public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
        {

            View bookItem = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.item_book, parent, false);


            TextView bookTitle = bookItem.FindViewById<TextView>(Resource.Id.bookTitle);
            ImageView coverImage = bookItem.FindViewById<ImageView>(Resource.Id.coverImage);
            CardView card = bookItem.FindViewById<CardView>(Resource.Id.card);

            MyView view = new MyView(bookItem) { mTitle = bookTitle, mCoverImage = coverImage, mCard = card};
            return view;
        }

        public override async void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
        {
            myHolder = holder as MyView;
            myHolder.mMainView.Click += mMainView_Click;
            myHolder.mTitle.Text = mBooks[position].Title;
            myHolder.mCoverImage.SetImageDrawable(mBooks[position].Cover.Drawable);
            myHolder.mCoverImageResourceID = mBooks[position].imageResourceId;

            if (position > mCurrentPosition)
            {
                int currentAnim = Resource.Animation.slide_left_to_right;
                //SetAnimation(myHolder.mMainView, currentAnim);
                mCurrentPosition = position;
            }

            Bitmap photo = await BitmapFactory.DecodeResourceAsync(mContext.Resources, myHolder.mCoverImageResourceID);
            BitmapDrawable bitmapDrawable = ((BitmapDrawable)mBooks[position].Cover.Drawable);
            Bitmap image = bitmapDrawable.Bitmap;

            var palette = Palette.From(photo).MaximumColorCount(16).Generate(this);


        }   

        public void OnGenerated(Palette palette)
        {

            if (palette == null)
                return;
            try
            {
                if (palette.LightVibrantSwatch != null)
                {
                    var lightVibrant = new Color(palette.LightVibrantSwatch.Rgb);
                    myHolder.mCard.SetCardBackgroundColor(lightVibrant);
                }
                if (palette.DarkVibrantSwatch != null)
                {
                    var darkVibrant = new Color(palette.DarkVibrantSwatch.Rgb);
                    myHolder.mCard.SetCardBackgroundColor(darkVibrant);
                }
            }
            catch (Exception ex)
            {

            }

        }

        public override int ItemCount
        {
            get { return mBooks.Count; }
        }
    }

RecyclerView所在的Fragment:

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {

        mRecyclerView = view.FindViewById<RecyclerView>(Resource.Id.booksRecyclerView);
        mBooks = new List<Book>();
        ImageView cover = new ImageView(Activity);

        cover.SetImageResource(Resource.Drawable.Torat_Hamachane1);
        mBooks.Add(new Book() { Title = "תורת המחנה א' - הלכות יום ויום", Cover = cover, imageResourceId = Resource.Drawable.Torat_Hamachane1}); 


        mLayoutManager = new GridLayoutManager(Activity, 2);
        mRecyclerView.SetForegroundGravity(GravityFlags.CenterHorizontal);
        mRecyclerView.SetLayoutManager(mLayoutManager);
        SimpleItemAnimator x = null;

        mRecyclerView.SetItemAnimator(x);
        mAdapter = new RecyclerAdapter(mBooks, mRecyclerView, Activity);
        mRecyclerView.SetAdapter(mAdapter);


        cover = new ImageView(Activity);
        cover.SetImageResource(Resource.Drawable.kitzurTHM);
        mBooks.Add(new Book() { Title = "קיצור תורת המחנה - הלכות יום ויום ושבת", Cover = cover, imageResourceId = Resource.Drawable.kitzurTHM });

        cover = new ImageView(Activity);
        cover.SetImageResource(Resource.Drawable.halkasPurim);
        mBooks.Add(new Book() { Title = "הלכה כסדרה - הלכות פורים", Cover = cover, imageResourceId = Resource.Drawable.halkasPurim });

        cover = new ImageView(Activity);
        cover.SetImageResource(Resource.Drawable.halkasPesach);
        mBooks.Add(new Book() { Title = "הלכה כסדרה - הלכות פסח", Cover = cover, imageResourceId= Resource.Drawable.halkasPesach });

        cover = new ImageView(Activity);
        cover.SetImageResource(Resource.Drawable.netzach);
        mBooks.Add(new Book() { Title = "שו\"ת נצח יהודה", Cover = cover , imageResourceId = Resource.Drawable.netzach});

        cover = new ImageView(Activity);
        cover.SetImageResource(Resource.Drawable.tankim);
        mBooks.Add(new Book() { Title = "טיפול בטנקים בשבת", Cover = cover , imageResourceId = Resource.Drawable.tankim});

        cover = new ImageView(Activity);
        cover.SetImageResource(Resource.Drawable.tipulBeChalalim);
        mBooks.Add(new Book() { Title = "טיפול בחללים בשבת", Cover = cover , imageResourceId = Resource.Drawable.tipulBeChalalim});

        return view;

    }

谁能帮我找出为什么只有最后两个项目有颜色?

谢谢!

更新: 开始赏金。急需帮助。

【问题讨论】:

标签: java c# android xamarin android-recyclerview


【解决方案1】:

我改变了一些东西,这是完整的适配器,我没有优化任何代码,但它可以工作。

总结如下:

var palette = Palette.From(((BitmapDrawable)myHolder.mCoverImage.Drawable).Bitmap).MaximumColorCount(16).Generate(new PalleteGeneration(myHolder));

这里是 PaleteGeneration:

public class PalleteGeneration : Java.Lang.Object, Palette.IPaletteAsyncListener
{
    private MyView _holder;

    public PalleteGeneration(MyView holder) 

        _holder = holder;
    }

    public void OnGenerated(Palette palette)
    {
        if (palette == null)
            return;

        if (palette.LightVibrantSwatch != null)
        {
            var lightVibrant = new Color(palette.LightVibrantSwatch.Rgb);
            _holder.mCard.SetCardBackgroundColor(lightVibrant);

        }
        else if (palette.LightMutedSwatch != null)
        {
            var lightVibrant = new Color(palette.LightMutedSwatch.Rgb);
            _holder.mCard.SetCardBackgroundColor(lightVibrant);

        }
        if (palette.DarkVibrantSwatch != null)
        {
            var darkVibrant = new Color(palette.DarkVibrantSwatch.Rgb);
            _holder.TitleBackground.SetBackgroundColor(darkVibrant);
        }
        else if (palette.DarkMutedSwatch != null)
        {
            var darkVibrant = new Color(palette.DarkMutedSwatch.Rgb);
            _holder.TitleBackground.SetBackgroundColor(darkVibrant);
        }               
}

获取完整的 RecyclerAdapter here

最终结果:

【讨论】:

  • 你的 onBindViewHolder 实现有误。你有 myHolder = holder 作为 MyView;这意味着 myHolder 每次 onBindViewholder 被调用时都会更新,所以到调色板操作完成时,所有的 onbindViewHolder 都会被调用,并且会有列表中最后一项的实例。您已经使用 Palette.From(((BitmapDrawable)myHolder.mCoverImage.Drawable).Bitmap 逃脱了它,因为在这里您正在传递每个实例。
  • 正如我在帖子中所说的,我没有优化任何以前的代码。我刚刚解决了 Pallete 的问题。您看到的适配器是我的 Pallete 修复后的用户原件。但感谢您的评论。
  • 实际上你应该重构你的代码,这就是我添加评论的原因。 myHolder = holder 因为 MyView 不是一个好习惯,你应该使用你的 viewholder 参考。你已经做到了,通过使用 var palette = Palette.From(((BitmapDrawable)myHolder.mCoverImage.Drawable).Bitmap).MaximumColorCount(16).Generate(new PalleteGeneration(myHolder));
  • 你不应该使用 MyView myHolder;并在 onBindVieHolder 中更新其实例,myHolder = holder as MyView;这不是一个可靠的实现
  • 我做了那个改变看看要点。但需要明确的是,字段 myHolder 仅在 onbindviewHolder 内部使用,因此没有问题。它不应该是一个字段,是的,我知道,但它是原始代码,我的主要重点是根据用户需要使托盘工作。我只是将其更改为仅在 onBindViewHolder 范围内的变量。现在好了。请让我们清洁 cmets 并只维护重要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-05
  • 1970-01-01
相关资源
最近更新 更多