简体   繁体   English

在recyclerview中滚动滚动背景颜色或图像?

[英]Background color or Images shuffling on scrolling in recyclerview?

I am wondering that my images and color of layouts shuffling when i scrolls downwards or upwards, I created cardview using recyclerview. 我想知道当我向下或向上滚动时,我的图像和布局颜色都在洗牌,我使用recyclerview创建了cardview。 and set an image(changes color on click like to know if its user's favourite item) and setbackgroundcolor(randomly chossen) to the parent layout to make cardview attractive. 并设置一个图像(在点击时更改颜色,以便知道其用户最喜欢的项目)和setbackgroundcolor(随机chossen)到父布局,以使cardview吸引人。 but when i scrolls 1. the image that image changes position, 2. the layout background changes color automatically. 但是当我滚动1.图像改变位置的图像,2。布局背景自动改变颜色。

I am posting my adapter's code here. 我在这里发布我的适配器代码。

public class TOAdapter extends RecyclerView.Adapter<TOAdapter.ViewHolder> {
JSONArray jsonArray;
private String title;
private String image;
private ImageLoader imageLoader;
private String subtitle;
private String subti;
private Context context;
private ImageView clip;

public TOAdapter(JSONArray jsonArray) {
    this.jsonArray = jsonArray;
}

// Create new views (invoked by the layout manager)
@Override
public TOAdapter.ViewHolder onCreateViewHolder(final ViewGroup parent,
                                               int viewType) {
    // create a new view
    View itemLayoutView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.top_twenty_list, parent, false);
    final ViewHolder viewHolder = new ViewHolder(itemLayoutView);


    final Random random = new Random(System.currentTimeMillis());// We add 155 since we want at least 155 in each channel.// Then we add to it a random number between 0 and 100.
    int r = 155 + random.nextInt(101);
    int g = 155 + random.nextInt(101);
    int b = 155 + random.nextInt(101);
    int color = Color.rgb(r, g, b);

    viewHolder.frame.setBackgroundColor(color);
    viewHolder.layer.setBackgroundColor(color);
    clip = (ImageView) itemLayoutView.findViewById(R.id.ic_clip);
    clip.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            int iColor = Color.parseColor("#0000FF");

            int red = (iColor & 0xFF0000) / 0xFFFF;
            int green = (iColor & 0xFF00) / 0xFF;
            int blue = iColor & 0xFF;

            float[] matrix = {0, 0, 0, 0, red
                    , 0, 0, 0, 0, green
                    , 0, 0, 0, 0, blue
                    , 0, 0, 0, 1, 0};

            ColorFilter colorFilter = new ColorMatrixColorFilter(matrix);
            clip.setColorFilter(colorFilter);
        }
    });


    return viewHolder;
}

// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(final ViewHolder viewHolder, int position) {

    // - get data from your itemsData at this position
    // - replace the contents of the view with that itemsData
    // myTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/RobotoCondensedBoldItalic.ttf");


    try {
        JSONObject obj = jsonArray.getJSONObject(position);
        title = obj.getString("title");
        image = obj.getString("brand_logo");
        subtitle = obj.getString("sub_title");
    } catch (JSONException e) {
        e.printStackTrace();
    }
    viewHolder.txtViewTitle.setText(subtitle);
    viewHolder.subtitle.setText(title);


    if (imageLoader == null)
        imageLoader = AppController.getInstance().getImageLoader();
    String full_Url = "http://mycompany/assets/new" + image;
    viewHolder.thumbnail.setImageUrl(full_Url, imageLoader);
    viewHolder.btn_get_deal.setTag(position);

    viewHolder.btn_get_deal.setOnClickListener(new View.OnClickListener() {
        public JSONObject obj;
        public ArrayList<String> offerlist = new ArrayList();

        @Override
        public void onClick(View view) {

            Intent offerpage = new Intent(AppController.getInstance().getApplicationContext(), OfferDetails.class);
            Integer pos = (Integer) view.getTag();
            try {
                obj = jsonArray.getJSONObject(pos);
                offerpage.putExtra("jsonObj", obj.toString());

            } catch (JSONException e) {
                e.printStackTrace();
            }

            //offerpage.getParcelableArrayListExtra(offerlist);
            offerpage.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            AppController.getInstance().getApplicationContext().startActivity(offerpage);
        }
    });


    //viewHolder.txtViewTitle.setTypeface(myTypeface);


}

// inner class to hold a reference to each item of RecyclerView
public static class ViewHolder extends RecyclerView.ViewHolder {

    private final NetworkImageView thumbnail;
    private final RelativeLayout frame;
    private final RelativeLayout layer;
    public TextView txtViewTitle;
    public TextView subtitle;
    public ImageView clip;
    public CardView btn_get_deal;


    public ViewHolder(View itemLayoutView) {
        super(itemLayoutView);
        txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.txttitle_toptwenty);
        subtitle = (TextView) itemLayoutView.findViewById(R.id.sub_title_toptwenty);
        thumbnail = (NetworkImageView) itemLayoutView.findViewById(R.id.thumbnail_topwenty);
        frame = (RelativeLayout) itemLayoutView.findViewById(R.id.frame);
        layer = (RelativeLayout) itemLayoutView.findViewById(R.id.layer);
        btn_get_deal = (CardView) itemLayoutView.findViewById(R.id.card_view);


    }

}


// Return the size of your itemsData (invoked by the layout manager)
@Override
public int getItemCount() {
    return jsonArray.length();
}

} }

I have created a working example of what you are trying to accomplish. 我已经创建了一个你要完成的工作示例。 The source of the errors you experience is mostly that you don't understand view recycling. 您遇到的错误来源主要是您不了解视图回收。 I am not going to explain the whole thing to you now, but anyway here is the example: 我现在不打算向你解释整个事情,但无论如何这里是一个例子:


For the example I used this layout for each row: 对于示例,我为每一行使用了此布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    android:id="@+id/background"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dp">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"/>

</FrameLayout>

I used this model: 我用过这个型号:

public class ExampleModel {

    private final int mColor;
    private final String mText;

    public ExampleModel(int color, String text) {
        mColor = color;
        mText = text;
    }

    public int getColor() {
        return mColor;
    }

    public String getText() {
        return mText;
    }
}

And this view holder: 这个观点持有人:

public class ExampleViewHolder extends RecyclerView.ViewHolder {

    private final FrameLayout mBackground;
    private final TextView mTextView;

    public ExampleViewHolder(View itemView) {
        super(itemView);

        mBackground = (FrameLayout) itemView.findViewById(R.id.background);
        mTextView = (TextView) itemView.findViewById(R.id.textView);
    }

    public void bind(ExampleModel model) {
        mBackground.setBackgroundColor(model.getColor());
        mTextView.setText(model.getText());
    }
}

As you can see nothing special, the Adapter implementation is equally simple: 正如您所看到的一样, Adapter实现同样简单:

public class ExampleAdapter extends RecyclerView.Adapter<ExampleViewHolder> {

    private final LayoutInflater mInflater;
    private final List<ExampleModel> mModels;

    public ExampleAdapter(Context context, List<ExampleModel> models) {
        mInflater = LayoutInflater.from(context);
        mModels = models;
    }

    @Override
    public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        final View itemView = mInflater.inflate(R.layout.item_example, parent, false);
        return new ExampleViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ExampleViewHolder holder, int position) {
        final ExampleModel model = mModels.get(position);
        holder.bind(model);
    }

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

And you use the whole thing like this: 而你使用这样的整个事情:

final Random mRandom = new Random(System.currentTimeMillis());

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    final List<ExampleModel> models = new ArrayList<>();
    for (int i = 0; i < 100; i++) {
        final int randomColor = generateRandomPastelColor();
        models.add(new ExampleModel(randomColor, String.valueOf(i)));
    }

    final ExampleAdapter adapter = new ExampleAdapter(getActivity(), models);
    recyclerView.setAdapter(adapter);
}

public int generateRandomPastelColor() {
    final int baseColor = Color.WHITE;

    final int red = (Color.red(baseColor) + mRandom.nextInt(256)) / 2;
    final int green = (Color.green(baseColor) + mRandom.nextInt(256)) / 2;
    final int blue = (Color.blue(baseColor) + mRandom.nextInt(256)) / 2;

    return Color.rgb(red, green, blue);
}

This should do what you are looking for and you can use it as an example of how to implement your Adapter . 这应该做你想要的,你可以用它作为如何实现你的Adapter一个例子。

I got the same problem ,when i used the radioButton in my listView row, I solved it. 我遇到了同样的问题,当我在listView行中使用radioButton时,我解决了它。 As in every scrolling the Cache is cleared, you have to store the changed data in every row. 在每次滚动时清除缓存,您必须将更改的数据存储在每一行中。 just check my code 只需检查我的代码

@Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
//      if(position==0)
//      Toast.makeText(context, ""+QuestionViewPageAdapter.mRadioGroupData, Toast.LENGTH_SHORT).show();

        final ViewHolder viewHolder;
        View row=convertView;

        radioButton=new RadioButton[Integer.parseInt(mNoOfCategoryGreading)];



            LayoutInflater inflater =LayoutInflater.from(context);//(LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.question_row, parent, false);

            viewHolder=new ViewHolder();

            viewHolder.tv_qContent=(TextView)row.findViewById(R.id.tv_question);
            viewHolder.rg=(RadioGroup)row.findViewById(R.id.rgrp);

            for(int i=0;i<Integer.parseInt(mNoOfCategoryGreading);i++)
            {
                radioButton[i]=new RadioButton(context);
                radioButton[i].setLayoutParams(new RadioGroup.LayoutParams(0, LayoutParams.WRAP_CONTENT,1f));
                //1f for layout_weight="1"
                radioButton[i].setId(i);
                radioButton[i].setText(""+(i+1));

                viewHolder.rg.addView(radioButton[i]);
            }
            row.setTag(viewHolder);


            for(int i=0;i<QuestionViewPageAdapter.mRadioGroupData.size();i++){
                int p=Integer.parseInt(""+QuestionViewPageAdapter.mRadioGroupData.get(i).get("position"));
                String id=QuestionViewPageAdapter.mRadioGroupData.get(i).get("Id");
                if(p!=-1 && id.equals(""+data.get(position).get(AppData.question_Set_category_QuestionID)))
                {//radioButton[p].setSelected(true);
                    viewHolder.rg.check(p-1);}
                //Toast.makeText(context, "Yes "+p, Toast.LENGTH_LONG).show();}
            }

        viewHolder.tv_qContent.setText((position+1)+". "+data.get(position).get(AppData.question_Set_category_QuestionContent));
        viewHolder.tv_qContent.setTypeface(typeface_muso_regular300);



        viewHolder.rg.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                // TODO Auto-generated method stub

                String s=data.get(position).get(AppData.question_Set_category_QuestionID);
                isAvailabel(s);


                        int radioButtonID = viewHolder.rg.getCheckedRadioButtonId();
                        View radioButton = viewHolder.rg.findViewById(radioButtonID);
                        int idx = viewHolder.rg.indexOfChild(radioButton);
                        HashMap<String, String> map=new HashMap<String, String>();
                        map.put("position", ""+(idx+1));
                        map.put("Id", ""+data.get(position).get(AppData.question_Set_category_QuestionID));
                        map.put("CategoryId", ""+mCategoryId);
                        QuestionViewPageAdapter.mRadioGroupData.add(map);
                }


        });





        return row;
    }

    private void isAvailabel(String qId){

        for(int i=0;i<QuestionViewPageAdapter.mRadioGroupData.size();i++){
            if(qId.equals(QuestionViewPageAdapter.mRadioGroupData.get(i).get("Id"))){
                position=i;

                QuestionViewPageAdapter.mRadioGroupData.remove(i);
            }
        }

    }

     class ViewHolder {
         TextView tv_qContent ,tv_1,tv_2,tv_3;
            RadioGroup rg;
            RadioButton rBtn1,rBtn2,rBtn3,rBtn4,rBtn5;
     }

In my case overriding getItemId and setting sethasStableIds to true solved the shuffling issue. 在我的情况下,重写getItemId并将sethasStableIds设置为true解决了混乱问题。

in adapter: 适配器:

    @Override
    public long getItemId(int position) {
    Object listItem = feeds.get(position);
    return listItem.hashCode();
    }

in main activity/fragment : 在主要活动/片段中:

    adapter = new FeedAdapter(feeds, getContext());
    adapter.setHasStableIds(true);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM