【问题标题】:Can't set different Drawables to recyclerview items无法将不同的 Drawable 设置为 recyclerview 项目
【发布时间】:2019-04-09 06:03:27
【问题描述】:

我有带有图片、文字和描述的回收站视图。

现在,当我从服务器获取数据时,我也得到了 HEX 颜色,并且有了它,在 Asynctask 中,应用程序将使用颜色作为色调来制作 Drawable。

但是当应用程序加载并完成时,所有可绘制的项目都与最后一个项目匹配。

如你所见,帽子颜色相同,但与数据库的十六进制不匹配:

日志也可以批准这个:

HatStoreFragment$JSONParse2:Hat Hex:#d61b22Hat 名称:Punainen Hattu HatStoreFragment$JSONParse2:Hat Hex:#fff202Hat 名称:Keltainen Hattu

我的适配器:

包 com.developerfromjokela.pusahub;

public class HatStoreAdapter extends RecyclerView.Adapter<HatStoreAdapter.MyViewHolder> {
    private String[] mDataset;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    private Context mContext;
    private List<HatStoreCard> appsList;
    private HatAdapterListener listener;


    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView title, count;
        public ImageView thumbnail, overflow;
        public CardView cardView;


        public MyViewHolder(View view) {
            super(view);
            title = (TextView) view.findViewById(R.id.hattitle);
            count = (TextView) view.findViewById(R.id.hatdesc);
            thumbnail = (ImageView) view.findViewById(R.id.hatthumbnail);
            overflow = (ImageView) view.findViewById(R.id.hatoverflow);
            cardView = view.findViewById(R.id.hatcard_view);
        }
    }


    public HatStoreAdapter(Context mContext, List<HatStoreCard> appsList, HatAdapterListener listener) {
        this.mContext = mContext;
        this.appsList = appsList;
        this.listener = listener;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.hatstorecardview, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, int postition) {
        HatStoreCard app = appsList.get(holder.getAdapterPosition());
        holder.title.setText(app.getName());
        holder.count.setText(app.getDescription());

        // loading album cover using Glide library
        if (CardAnimationConfig.animating) {
            setFadeAnimation(holder.cardView);
        }


        Glide.with(mContext).load(app.getAppicon()).into(holder.thumbnail);

        Log.e(getClass().getName(), "Drawable: "+ app.getAppicon().toString());
        holder.overflow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showPopupMenu(holder.overflow);
            }
        });
        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                listener.onHatSelected(holder.getAdapterPosition(), HatDetailsArrayHelper.getTitle(holder.getAdapterPosition()), HatDetailsArrayHelper.getDescription(holder.getAdapterPosition()), HatDetailsArrayHelper.getThumbnailImage(holder.getAdapterPosition()), HatDetailsArrayHelper.getType(holder.getAdapterPosition()), HatDetailsArrayHelper.getPrice(holder.getAdapterPosition()), HatDetailsArrayHelper.getDownloadableRes(holder.getAdapterPosition()), appsList.get(holder.getAdapterPosition()).getRequiredVersion(), appsList.get(holder.getAdapterPosition()).getHatID());
            }
        });

        holder.thumbnail.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                listener.onHatSelected(holder.getAdapterPosition(), HatDetailsArrayHelper.getTitle(holder.getAdapterPosition()), HatDetailsArrayHelper.getDescription(holder.getAdapterPosition()), HatDetailsArrayHelper.getThumbnailImage(holder.getAdapterPosition()), HatDetailsArrayHelper.getType(holder.getAdapterPosition()), HatDetailsArrayHelper.getPrice(holder.getAdapterPosition()), HatDetailsArrayHelper.getDownloadableRes(holder.getAdapterPosition()), appsList.get(holder.getAdapterPosition()).getRequiredVersion(), appsList.get(holder.getAdapterPosition()).getHatID());
            }
        });
    }

    /**
     * Showing popup menu when tapping on 3 dots
     */
    private void showPopupMenu(View view) {
        // inflate menu
        PopupMenu popup = new PopupMenu(mContext, view);
        MenuInflater inflater = popup.getMenuInflater();
        inflater.inflate(R.menu.storecard_menu, popup.getMenu());
        popup.setOnMenuItemClickListener(new MyMenuItemClickListener());
        popup.show();
    }

    /**
     * Click listener for popup menu items
     */
    class MyMenuItemClickListener implements PopupMenu.OnMenuItemClickListener {

        public MyMenuItemClickListener() {
        }

        @Override
        public boolean onMenuItemClick(MenuItem menuItem) {
            switch (menuItem.getItemId()) {
                case R.id.action_download:
                    Toast.makeText(mContext, "Ladataan", Toast.LENGTH_SHORT).show();
                    return true;
                default:
            }
            return false;
        }
    }

    @Override
    public int getItemCount() {
        return appsList.size();
    }

    public interface HatAdapterListener {

        void onHatSelected(int position, String hatname, String hatdescription, String hatthumbnail, String hattype, int hatprice, String appdownloadableres, int requiredversion, int hatID);
    }

    public Intent getItemIntent(int postition, Context context) {
       Intent intent =  intents.get(postition);
       return intent;
    }
    private void setFadeAnimation(View view) {
        AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
        anim.setDuration(200);
        view.startAnimation(anim);
    }




}

还有 HatStoreCard 类:

public class HatStoreCard {
    private String name;
    private String description;
    private Drawable appicon;
    private int hatID;
    private int requiredVersion;

    public HatStoreCard() {
    }

    public HatStoreCard(String name, String description, Drawable haticon, int requiredVersion, int hatID) {
        this.name = name;
        this.description = description;
        this.appicon = haticon;
        this.requiredVersion = requiredVersion;
        this.hatID = hatID;
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getRequiredVersion() {
        return requiredVersion;
    }

    public int getHatID() {
        return hatID;
    }

    public void setHatID(int hatID) {
        this.hatID = hatID;
    }

    public void setRequiredVersion(int version) {
        this.requiredVersion = version;
    }

    public void setAppicon(Drawable appicon) {
        this.appicon = appicon;
    }
    public Drawable getAppicon() {
        return appicon;
    }
}

我希望有足够的日志和信息。

如果有人能说出为什么会这样,非常感谢他。

编辑: 这是制作 Drawable 的代码:

if (apptype.equals("tint")) {

                        Drawable icon = getResources().getDrawable(R.drawable.ic_hat_cropped_v3);
                        icon.setTintMode(MULTIPLY);
                        icon.setTint(Color.parseColor(appdownloadableres));
                        Log.e(getClass().getName(), "Hat Hex: "+appdownloadableres+ "Hat name: "+apptitle);


                        final HatStoreCard a = new HatStoreCard(apptitle, appshortdesc, icon, supportversion, hatID);
                        getActivity().runOnUiThread(() -> {

                            // Stuff that updates the UI
                              appsList.add(a);


                        });
                    }

如果这是重复的,我很抱歉,我没有找到答案(也许我的英语知识不好,所以我没有搜索正确的问题来获得我需要的答案)。

问候, 来自 Jokela 的开发者

【问题讨论】:

  • appdownloadableres 是如何分配的?
  • 'appdownloadableres' 来自 JSONObject,它来自服务器。所以,appdowbloadableres 不会有问题,因为从 JSONObject 中获取字符串不是问题,因为帽子名称不同且正确。
  • 我只是确保您没有分配相同的值

标签: android drawable


【解决方案1】:

每次从资源加载Drawable 对象时,您都会获得一个唯一的Drawable 对象实例。 然而,这些独特的drawable中的每一个都将共享一个Drawable.ConstantState对象。当您修改可绘制对象的色调时,这是该常量状态的一部分,因此即使看起来您正在修改唯一的可绘制对象,您实际上也会影响从同一资源加载的所有其他可绘制对象。

当你不想要这个优化时,你可以在加载的drawable上调用mutate()方法。所以,替换这段代码:

Drawable icon = getResources().getDrawable(R.drawable.ic_hat_cropped_v3);
icon.setTintMode(MULTIPLY);
icon.setTint(Color.parseColor(appdownloadableres));

用这个:

Drawable icon = getResources().getDrawable(R.drawable.ic_hat_cropped_v3);
icon.mutate();
icon.setTintMode(MULTIPLY);
icon.setTint(Color.parseColor(appdownloadableres));

【讨论】:

  • 谢谢!很棒的工作!非常感谢你,这正在工作!
【解决方案2】:

在监听器中改变你的项目后,你应该通知你的项目发生了什么变化,所以调用适配器方法notifyDataSetChanged(),它发出信号以重绘回收。

或者,如果您想要更高的性能,请使用notifyItemChanged(index),其中 index 是您的元素位置。

因此,在您的情况下,您的侦听器中还有一个参数(对适配器的引用),并在此方法的最后调用我提到的方法之一。

【讨论】:

  • 我应该把它放在哪里?我有'adapter.notifyDatasetChanged();'在 AsyncTask 的 On Post 执行中,后台的代码已经完成。
  • 发布你的监听类,你应该把它放在你的方法onHatSelected
【解决方案3】:

它对我有用:

Drawable icon = getResources().getDrawable(R.drawable.ic_hat_cropped_v3);
icon.setColorFilter(Color.parseColor(appdownloadableres), MULTIPLY);
image.setBackgroundDrawable(icon);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多