web-dev-qa-db-fra.com

La méthode getView () de l’adaptateur personnalisé n’est pas appelée

Voici le code du fragment dans lequel je mets un adaptateur personnalisé à la liste. 

Il n'y a pas d'erreur mais la ListView est vide. J'ai implémenté getCount() qui renvoie le bon nombre d'éléments dans ma liste de tableaux. Je ne vois pas ("Inside", "GetView") dans le logcat

Fragment

public class ServiceCarListFragment extends Fragment {

    private String url;
    private ArrayList<CarDetail> carDetailList = new ArrayList<CarDetail>();
    private CarListAdapter adapter;
    private ListView mList;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        url = getActivity().getIntent().getStringExtra("url");
        new DownloadCarDetail().execute(url);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View v = inflater.inflate(R.layout.fragment_service_car_list, container, false);
        mList = (ListView) v.findViewById(R.id.list);
        mList.setAdapter(adapter);

        for (CarDetail car : carDetailList) {
            // START LOADING IMAGES FOR EACH STUDENT
            car.loadImage(adapter);
        }
        return v;
    }

    class DownloadCarDetail extends AsyncTask<String, String, ArrayList<CarDetail>> {

        @Override
        protected ArrayList<CarDetail> doInBackground(String... params) {
            // TODO Auto-generated method stub
            ArrayList<CarDetail> carDetailList = JsonParser.parseJson(params[0]);
            return carDetailList;
        }

        @Override
        protected void onPostExecute(ArrayList<CarDetail> carDetailList) {
            // TODO Auto-generated method stub
            ServiceCarListFragment.this.carDetailList = carDetailList;
            Log.d("dccs", String.valueOf(ServiceCarListFragment.this.carDetailList.size()));
            adapter = new CarListAdapter(getActivity(), ServiceCarListFragment.this.carDetailList);
            Log.d("dccs", String.valueOf((adapter.getCount())));
        }

    }
}

CustomAdapter

public class CarListAdapter extends BaseAdapter {

    private ArrayList<CarDetail> items = new ArrayList<CarDetail>();
    private Context context;

    public CarListAdapter(Context context, ArrayList<CarDetail> items) {
        this.context = context;
        this.items = items;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return items.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return items.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        Log.d("Inside", "GetView");
        LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        ViewHolder holder = null;
        CarDetail car = items.get(position);

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.car_list_row, null);
            holder = new ViewHolder();
            holder.tvCarName = (TextView) convertView.findViewById(R.id.tvCarName);
            holder.tvDailyPriceValue = (TextView) convertView.findViewById(R.id.tvWeeklyPriceValue);
            holder.tvWeeklyPriceValue = (TextView) convertView.findViewById(R.id.tvWeeklyPriceValue);
            holder.imgCar = (ImageView) convertView.findViewById(R.id.imgCar);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.tvCarName.setText(car.getCarName());
        if (car.getImage() != null) {
            holder.imgCar.setImageBitmap(car.getImage());
        } else {
            // MY DEFAULT IMAGE
            holder.imgCar.setImageResource(R.drawable.ic_action_call);
        }

        return convertView;
    }

    static class ViewHolder {
        TextView tvCarName;
        TextView tvDailyPriceValue;
        TextView tvWeeklyPriceValue;
        ImageView imgCar;
    }

}
33
Ravi

Les seules raisons pour lesquelles getView n'est pas appelé sont:

  1. getCount renvoie 0.
  2. vous oubliez d'appeler setAdapter sur le ListView.
  3. Si la visibilité de ListView (ou de son conteneur) est GONE. Merci à @ TaynãBonaldo pour sa précieuse contribution.
  4. ListView n'est associé à aucune disposition de fenêtre. C'est-à-dire que mListView = new ListView(...) est utilisé sans myLayout.addView(mListView).

Dans onPostExcute, après avoir créé une nouvelle instance de CarListAdapter, je vous proposerai de mettre à jour la nouvelle instance sur votre ListView. En effet, vous devez rappeler

 mList.setAdapter(adapter);

Edit: setAdapter devrait toujours être appelé sur le thread ui pour éviter les comportements inattendus

Edit2:

La même chose s'applique à RecyclerView. Sois sûr que

  • getItemCount renvoie une valeur supérieure à 0 (généralement la taille du jeu de données)
  • setLayoutManager et setAdapter doivent être appelés sur le UI Thread
  • La visibilité du widget doit être définie sur VISIBLE
149
Blackbelt

vous devez vérifier que la liste contient des éléments pouvant contenir une erreur lors de l'ajout d'éléments à votre liste ..__ Pour vérifier, utilisez la méthode suivante:

adapter.getCount();
5
Luis Felipe

J'ai fait face à un problème similaire. Voici un moyen simple de le résoudre:

Dans votre onCreateView, vous devrez attendre avant que la vue soit créée. Alors changez vos lignes à partir de ceci:

mList = (ListView)v.findViewById(R.id.list);
mList.setAdapter(adapter);

CHANGEZ LES DEUX LIGNES CI-DESSUS EN:

mList = (ListView)v.findViewById(R.id.list);
mList.post(new Runnable() {
    public void run() {
        mList.setAdapter(adapter);
    }
});

J'espère que cela aidera d'autres personnes qui rencontreraient un problème similaire

3
Gaurav Srivastava

J'ai eu le même problème. Et après avoir essayé tous les conseils ci-dessus, mon getView n'était toujours pas appelé. J'ai donc essayé de supprimer le ScrollView que j'ai utilisé en dehors de ListView. Ensuite, le getView a bien fonctionné. Juste pour ajouter une dernière posibilité. J'espère aider quelqu'un.

0
DaniloLM

Ce que vous avez fait est

Dans votre adaptateur

public CarListAdapter(Context context , ArrayList<CarDetail> items) {

    this.context = context;
    this.items = items;

}

dans votre fragment

adapter = new CarListAdapter(getActivity(),ServiceCarListFragment.this.carDetailList);

J'espère que vous utiliserez FragmentActivity

Vous devez appeler 

adapter = new CarListAdapter(YOUR_ACTIVITY_CONTEXT, carDetailList);

YOUR_ACTIVITY_CONTEXT sera votre FragmentActivity

0
Ameer Moaaviah

Il vous manque la super classe dans le constructeur. Voir mon exemple ci-dessous:

public AppDataAdapter(Activity a, int textViewResourceId, ArrayList<AppData> entries) {
    super(a, textViewResourceId, entries);
    this.entries = entries;
    this.activity = a;
}
0
o0rebelious0o