Color de fondo o imágenes barajando en desplazamiento en recyclerview?

Me pregunto que mis imágenes y el color de los diseños de barajar cuando me desplaza hacia abajo o hacia arriba, he creado cardview utilizando recyclerview. Y establecer una imagen (cambia de color al hacer clic como para saber si el elemento favorito de su usuario) y setbackgroundcolor (al azar chossen) a la disposición de los padres para hacer cardview atractivo. Pero cuando se desplaza 1. la imagen que la imagen cambia de posición, 2. el fondo de diseño cambia de color automáticamente.

Estoy publicando el código de mi adaptador aquí.

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

}

He creado un ejemplo práctico de lo que estás tratando de lograr. La fuente de los errores que experimenta es sobre todo que usted no entiende reciclar la vista. No voy a explicarle todo ahora, pero de todos modos aquí está el ejemplo:


Para el ejemplo he utilizado este diseño para cada fila:

 <?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> 

Utilicé este modelo:

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

Y este titular de la opinión:

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

Como no se ve nada especial, la implementación del Adapter es igualmente 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(); } } 

Y usas todo esto como esto:

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

Esto debe hacer lo que está buscando y puede utilizarlo como un ejemplo de cómo implementar su Adapter .

Tengo el mismo problema, cuando utilicé el radioButton en mi fila listView, lo resolví. Como en todos los desplazamientos, el caché se borra, debe almacenar los datos modificados en cada fila. Solo revisa mi código

 @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; } 

En mi caso, sobreescribir getItemId y establecer sethasStableIds en true solucionó el problema de barajadura.

En el adaptador:

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

En la actividad principal / fragmento:

  adapter = new FeedAdapter(feeds, getContext()); adapter.setHasStableIds(true); 
  • NotifyItemChanged (int position) actualiza varios elementos en RecyclerView
  • Uso de JsonArray vs ArrayList como conjunto de datos para RecyclerView Adapter
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.