studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android button gridview baseadapter

para - manual de programacion android pdf



Evite que el adaptador recicle las vistas en el desplazamiento (4)

Tengo un adaptador base personalizado que tomará una lista de datos. Desde aquí completará una vista de cuadrícula con botones personalizados. Lo hace perfectamente y llena el gridview. El problema es. Quiero establecer un botón para cambiar los colores en el cambio. Cuando hago esto, dado que la vista se recicla, también cambia la siguiente vista que se recicla. Ex. Haga clic en el botón uno en la posición 0. También cambia el botón en la posición 13. Ahora cuando realizo alguna depuración, descubro que también cambia algunas de las propiedades. Me pregunto si hay alguna forma de crear mi vista tal como es sin necesidad de reciclar ninguna parte de las vistas.

He visto algunas cosas sobre el uso de stableID, pero incluso cuando lo he reemplazado por verdadero. Todavía no lo cambia actualmente.

static class CategoryButtonAdapter extends BaseAdapter { private Context mContext; private ArrayList<DishCategory> dishCategories; private ArrayList<Dish> dishItems; static ArrayList<DishCategoryButton> mDishCategoryButtons; //will take in an array list created in the orderlayout that will be the //dish category. This will be the from where we will the count for the adapter public CategoryButtonAdapter(Context context, ArrayList<DishCategory> dishCategories) { this.mContext = context; this.dishCategories = dishCategories; dishItems = dishCategories.get(0).getDishes(); } public int getCount() { return dishCategories.size(); } //to be implementated later so it can b3e used to find menu categories @Override public DishCategory getItem(int position) { return dishCategories.get(position); } public void getDishCategoryButtons() { if(mDishCategoryButtons.size() == 0) { System.out.println("The number of buttons in this adapapter is " + mDishCategoryButtons.size()); } else { System.out.println("The number of buttons in this adapapter is " + mDishCategoryButtons.size()); } } public long getItemId(int position) { return dishCategories.get(position).getDishCategoryID(); } @Override public boolean hasStableIds() { //return super.hasStableIds(); //To change body of generated methods, choose Tools | Templates. return true; } public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; DishCategoryButton button = null; //button to be created if(convertView == null ) { holder = new ViewHolder(); //if it is not recycled, initialize some new attributes button = new DishCategoryButton(this.mContext,dishCategories.get(position)); button.setLayoutParams(new GridView.LayoutParams(100,100)); button.setPadding(2,2,2,2); //convertView.setTag(holder); button.setTag(holder); } else { //holder = (ViewHolder)convertView.getTag(); button = (DishCategoryButton) convertView; } //setButton to the description of the category //mDishCategoryButtons.add(button); button.setText((dishCategories.get(position).getDescription())); //this can be changed later to change the sex appeal of the app //for now it will be plain button.setId(position); //.setOnClickListener(new View.OnClickListener() button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Perform action on click DishCategoryButton dishCategoryButton = (DishCategoryButton)v; PaintDrawable drawable = (PaintDrawable) dishCategoryButton.getBackground(); System.out.println("Dish button position is " + dishCategoryButton.getId()); //System.out.println("The position from the array says it is at " + position); System.out.println("Dish Category is " + dishCategoryButton.getDishCategory().getDescription()); System.out.println("Is it currently selected " + dishCategoryButton.getIsSelected()); int color = drawable.getPaint().getColor(); System.out.println("Color is " + color); dishCategoryButton.setIsSelected(true); drawable = (PaintDrawable) dishCategoryButton.getBackground(); color = drawable.getPaint().getColor(); System.out.println("Color is " + color); System.out.println("hi"); // The toggle is enabled } }); //new loadDishItems(categoryButtons.get(position).getDescription())); return button; }

No te preocupes por el titular de la vista. eso fue un intento de prevenir el reciclaje. ¿Alguna pista o idea sobre cómo obtener esto?

Aquí está mi botón

public class DishCategoryButton extends Button { private DishCategory dishCategory = new DishCategory(); private Boolean isSelected = false; public DishCategoryButton(Context context, DishCategory dishCategory) { super(context); this.dishCategory = dishCategory; isSelected = false; setTextColor(Color.WHITE); setBackgroundDrawable(new PaintDrawable(Color.BLACK)); } public DishCategory getDishCategory() { return dishCategory; } public void setDishCategory(DishCategory dishCategory) { this.dishCategory = dishCategory; } public Boolean getIsSelected() { return isSelected; } public void setIsSelected(Boolean isSelected) { this.isSelected = isSelected; if(isSelected == true) { setTextColor(Color.WHITE); setBackgroundDrawable(new PaintDrawable(Color.GREEN)); } else { setTextColor(Color.WHITE); setBackgroundDrawable(new PaintDrawable(Color.BLACK)); } }

}


Evite que el adaptador recicle las vistas en el desplazamiento

Simplemente no use el convertView pasado a getView() y siempre devuelva una View recién generada.

Sin embargo, esta es una mala solución en términos de rendimiento. En cambio, su objetivo no debe ser evitar el reciclado, sino reciclarlo correctamente : su getView() debería restablecer el convertView a su estado prístino.

Por lo tanto, si se produce un cambio en el hecho de que algunas de las propiedades de su Button se modifican con respecto a sus valores no predeterminados, reinícielas a los valores predeterminados en getView() .


public View getView(int position, View convertView, ViewGroup parent) { View itemview = null; itemview = getLayoutInflater().inflate(R.layout.ordermini, parent,false); }

Esto ayudará a inflar una nueva vista


Un mejor enfoque sería usar

recyclerView.getRecycledViewPool().setMaxRecycledViews(VIEW_TYPE,0);

Debe tener en cuenta que esto puede reducir el rendimiento de su RecyclerView.

Puede anular el método getItemViewType como se menciona a continuación

@Override public int getItemViewType(int position) { if (position == feedElements.size()) return 3; else if (feedElements.get(position).getType() == 1) return 1; else return 2; }


Tenía este problema exacto. Así que agregué un código para verificar cada vista que no estaba resaltada y cuando encontró la vista resaltada, la cambió nuevamente.

//--------SET-FOREGROUND-IMAGE-(BORDER)------------ /*If the user clicks on an item and then scrolls down so the selected item is no longer in view Then the Item that the user clicked on will be recycled with the foreground image. This is BAD because when the user sees the selected item (as distinguished by it''s different border) it will be holding different data from a different data model item. These following lines of code will change the colour of any non selected item back to normal and they will colour of the selected views appropriately*/ if(currentLine.getLineId() == clickedId) {recycleHolder.cardView.setForeground(parentActivity.getResources().getDrawable(R.drawable.card_view_border_selected));} else {recycleHolder.cardView.setForeground(parentActivity.getResources().getDrawable(R.drawable.card_view_border));}

y este código se coloca dentro de

@Override public void onBindViewHolder(final RecyclableViewHolder recycleHolder, int i) { }