Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
225 views
in Technique[技术] by (71.8m points)

java - 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. 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. but when i scrolls 1. the image that image changes position, 2. the layout background changes color automatically.

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();
}

}

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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:

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...