NotifyDataSetChanged no funciona en RecyclerView
Estoy recibiendo datos del servidor y luego analizándolo y almacenándolo en una lista. Estoy usando esta lista para el adaptador de RecyclerView. Estoy usando Fragmentos.
Estoy usando un Nexus 5 con KitKat. Estoy usando la biblioteca de soporte para esto. ¿Esto hará una diferencia?
- Ocultar barra de desplazamiento de RecyclerView
- ¿Cómo animar recyclerview en desplazamiento como Google plus / Google newsstand?
- Cómo usar RecyclerView, Tratando de seguir la sugerencia de developer.android.com pero obtener un error
- Los elementos no tienen el mismo ancho cuando se utiliza RecyclerView GridLayoutManager para establecer el espaciado de columnas por ItemDecoration
- Android RecyclerView último elemento eliminar (tiempo de ejecución) error
Aquí está mi código: (Usando datos ficticios para la pregunta)
Variables de los miembros:
List<Business> mBusinesses = new ArrayList<Business>(); RecyclerView recyclerView; RecyclerView.LayoutManager mLayoutManager; BusinessAdapter mBusinessAdapter;
Mi onCreateView()
:
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Getting data from server getBusinessesDataFromServer(); View view = inflater.inflate(R.layout.fragment_business_list, container, false); recyclerView = (RecyclerView) view .findViewById(R.id.business_recycler_view); recyclerView.setHasFixedSize(true); mLayoutManager = new LinearLayoutManager(getActivity()); recyclerView.setLayoutManager(mLayoutManager); mBusinessAdapter = new BusinessAdapter(mBusinesses); recyclerView.setAdapter(mBusinessAdapter); return view; }
Después de obtener datos del servidor, se llama parseResponse()
.
protected void parseResponse(JSONArray response, String url) { // insert dummy data for demo mBusinesses.clear(); Business business; business = new Business(); business.setName("Google"); business.setDescription("Google HeadQuaters"); mBusinesses.add(business); business = new Business(); business.setName("Yahoo"); business.setDescription("Yahoo HeadQuaters"); mBusinesses.add(business); business = new Business(); business.setName("Microsoft"); business.setDescription("Microsoft HeadQuaters"); mBusinesses.add(business); Log.d(Const.DEBUG, "Dummy Data Inserted\nBusinesses Length: " + mBusinesses.size()); mBusinessAdapter = new BusinessAdapter(mBusinesses); mBusinessAdapter.notifyDataSetChanged(); }
Mi BusinessAdapter:
public class BusinessAdapter extends RecyclerView.Adapter<BusinessAdapter.ViewHolder> { private List<Business> mBusinesses = new ArrayList<Business>(); // Provide a reference to the type of views that you are using // (custom viewholder) public static class ViewHolder extends RecyclerView.ViewHolder { public TextView mTextViewName; public TextView mTextViewDescription; public ImageView mImageViewLogo; public ViewHolder(View v) { super(v); mTextViewName = (TextView) v .findViewById(R.id.textView_company_name); mTextViewDescription = (TextView) v .findViewById(R.id.textView_company_description); mImageViewLogo = (ImageView) v .findViewById(R.id.imageView_company_logo); } } // Provide a suitable constructor (depends on the kind of dataset) public BusinessAdapter(List<Business> myBusinesses) { Log.d(Const.DEBUG, "BusinessAdapter -> constructor"); mBusinesses = myBusinesses; } // Create new views (invoked by the layout manager) @Override public BusinessAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { Log.d(Const.DEBUG, "BusinessAdapter -> onCreateViewHolder()"); // create a new view View v = LayoutInflater.from(parent.getContext()).inflate( R.layout.item_business_list, parent, false); ViewHolder vh = new ViewHolder(v); return vh; } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(ViewHolder holder, int position) { // - get element from your dataset at this position // - replace the contents of the view with that element Log.d(Const.DEBUG, "BusinessAdapter -> onBindViewHolder()"); Business item = mBusinesses.get(position); holder.mTextViewName.setText(item.getName()); holder.mTextViewDescription.setText(item.getDescription()); holder.mImageViewLogo.setImageResource(R.drawable.ic_launcher); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { Log.d(Const.DEBUG, "BusinessAdapter -> getItemCount()"); if (mBusinesses != null) { Log.d(Const.DEBUG, "mBusinesses Count: " + mBusinesses.size()); return mBusinesses.size(); } return 0; } }
Pero no obtengo los datos mostrados en la vista. ¿Qué estoy haciendo mal?
Aquí está mi registro,
07-14 21:15:35.669: D/xxx(2259): Dummy Data Inserted 07-14 21:15:35.669: D/xxx(2259): Businesses Length: 3 07-14 21:26:26.969: D/xxx(2732): BusinessAdapter -> constructor
No recibo ningún registro después de esto. ¿No debería volver a llamar a getItemCount()
en el adaptador?
- Causa de NullPointerException android.support.v7.widget.RecyclerView.onMeasure
- ScrollBy no funciona correctamente en recyclerview anidado
- No hay adaptador conectado; Saltar el diseño
- RecyclerView no se desinscribe del adaptador en el cambio de orientación
- RecyclerView y DiffUtil - Una pesadilla de concurrencia
- El adaptador de RecyclerView notifyDataSetChanged no funciona
- Android: ¿Cómo obtener el actual desplazamiento X de RecyclerView?
- SetLayoutManager NullPointException en RecyclerView
En su parseResponse()
está creando una nueva instancia de la clase BusinessAdapter
, pero en realidad no la está utilizando en ninguna parte, por lo que su RecyclerView
no sabe que la nueva instancia existe.
Usted necesita:
- Llame a
recyclerView.setAdapter(mBusinessAdapter)
nuevo para actualizar la referencia del adaptador de RecyclerView para que apunte a su nuevo - O simplemente eliminar
mBusinessAdapter = new BusinessAdapter(mBusinesses);
Para continuar utilizando el adaptador existente. Puesto que no ha cambiado la referencia demBusinesses
, el adaptador seguirá utilizando esa lista de arreglos y se actualizará correctamente al llamar anotifyDataSetChanged()
.
Pruebe este método:
List<Business> mBusinesses2 = mBusinesses; mBusinesses.clear(); mBusinesses.addAll(mBusinesses2); //and do the notification
Un poco de tiempo, pero debe funcionar.
Tuve el mismo problema. Acabo de solucionarlo con declarar el adapter
público antes onCreate
de clase.
PostAdapter postAdapter;
después de esto
postAdapter = new PostAdapter(getActivity(), posts); recList.setAdapter(postAdapter);
Al fin he llamado:
@Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); // Display the size of your ArrayList Log.i("TAG", "Size : " + posts.size()); progressBar.setVisibility(View.GONE); postAdapter.notifyDataSetChanged(); }
Que esto te ayude.
- Android 4.3: Cómo conectarse a varios dispositivos Bluetooth Low Energy
- Agregar botón positivo / negativo al cuadro de diálogo de DialogFragment