Первый элемент в Custom BaseAdapter не отображается в Gridview, а ClickListener в Gridview не работает

Я два дня сижу только для того, чтобы поискать и найти, что не так с кодом моего фрагмента gridview и адаптера. первый элемент не отображается в моем представлении сетки.

Это мой код фрагмента

public class FragmentConsumerHomeCanteen extends Fragment {

    private final String TAG = "ConsumerHomeCanteen";
    private GridView fchCanGrid;
    private ArrayList<CanteenRecordDetails> canteenRecordDetailsArrayList;
    private CanteenAdapter canteenAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_consumer_home_canteen, container, false);

        resourceVariables(view);

        canteenRecordDetailsArrayList = new ArrayList<>();
        canteenRecordDetailsArrayList.clear();
        CafeTreydDatabase cafeTreydDatabase = new CafeTreydDatabase(getActivity());
        Cursor cursor = cafeTreydDatabase.getCanteenForConsumerHomeCanteen(TAG);
        if (cursor.moveToFirst()) {
            while (cursor.moveToNext()) {
                int id = cursor.getInt(0);
                String name = cursor.getString(1);
                String open = cursor.getString(2);
                String close = cursor.getString(3);
                byte[] image = cursor.getBlob(4);

                canteenRecordDetailsArrayList.add(new CanteenRecordDetails(id, name, open, close, image));
                canteenAdapter = new CanteenAdapter(getActivity(), canteenRecordDetailsArrayList);
                canteenAdapter.notifyDataSetChanged();
            }
            fchCanGrid.setAdapter(canteenAdapter);
            Log.i(TAG, "Setting adapter to GridView Successful");
        } else {
            Log.i(TAG, "Cursor returns null");
        }

        return view;
    }

    private void resourceVariables(View view) {
        fchCanGrid = view.findViewById(R.id.fchCanGrid);
        Log.i(TAG, "Resourcing Successful");
    }

    private static class CanteenRecordDetails {

        private int id;
        private String name;
        private String open;
        private String close;
        private byte[] image;

        private CanteenRecordDetails(int id, String name, String open, String close, byte[] image) {
            this.id = id;
            this.name = name;
            this.open = open;
            this.close = close;
            this.image = image;
        }

        private int getId() {
            return id;
        }

        private String getName() {
            return name;
        }

        private String getOpen() {
            return open;
        }

        private String getClose() {
            return close;
        }

        private byte[] getImage() {
            return image;
        }

    }

    private static class CanteenAdapter extends BaseAdapter{

        private final Context context;
        private final ArrayList<CanteenRecordDetails> canteenRecordDetailsArrayList;
        private final LayoutInflater layoutInflater;

        private CanteenAdapter(Context context, ArrayList<CanteenRecordDetails> canteenRecordDetailsArrayList) {
            this.context = context;
            this.canteenRecordDetailsArrayList = canteenRecordDetailsArrayList;
            layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public int getCount() {
            return canteenRecordDetailsArrayList.size();
        }

        @Override
        public Object getItem(int position) {
            return canteenRecordDetailsArrayList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = layoutInflater.inflate(R.layout.layout_fragment_consumer_home_canteen, parent, false);
            }
            LinearLayout lfchcLL = convertView.findViewById(R.id.lfchCanLL);
            TextView lfchCanName = convertView.findViewById(R.id.lfchCanName);
            TextView lfchCanOpen = convertView.findViewById(R.id.lfchCanOpen);
            TextView lfchCanClose = convertView.findViewById(R.id.lfchCanClose);
            ImageView lfchCanImage = convertView.findViewById(R.id.lfchCanImage);

            CanteenRecordDetails canteenRecordDetails = canteenRecordDetailsArrayList.get(position);
            lfchCanName.setText(canteenRecordDetails.getName());
            lfchCanOpen.setText(String.format("OPEN: %s", canteenRecordDetails.getOpen()));
            lfchCanClose.setText(String.format("CLOSE: %s", canteenRecordDetails.getClose()));
            byte[] tempImage = canteenRecordDetails.getImage();
            Bitmap bitmap = BitmapFactory.decodeByteArray(tempImage, 0, tempImage.length);
            lfchCanImage.setImageBitmap(bitmap);

            lfchcLL.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(context, lfchCanName.getText(), Toast.LENGTH_SHORT).show();
                    String TAG = "ConsumerHomeCanteen";
                    try {
                        ((ActivityConsumerHome)context).setCanteenId(canteenRecordDetails.getId());
                        ((ActivityConsumerHome)context).setCanteenName(canteenRecordDetails.getName());
                        Navigation.findNavController(parent).navigate(R.id.action_fragmentConsumerHomeCanteen_to_fragmentConsumerHomeCategory);
                        Log.i(TAG, "Navigating to next Fragment");
                    } catch (Exception e) {
                        e.printStackTrace();
                        Log.i(TAG, "Failed to set canteenId");
                    }
                }
            });

            return convertView;
        }
    }
}

Если вы заметили, я поместил onclickListener для макета внутрь getView в адаптере, потому что я не могу использовать onItemClickListener на GridView. это не работает. какое бы решение я ни видел в Интернете, оно не работает.

gridview по-прежнему пропускает первый пункт на адаптере. Я использовал информационный журнал, чтобы убедиться, что база данных и arraylist работают нормально. Это работает нормально. Думаю, проблема только в griview.


1
53
1

Ответ:

Решено

Проблема: Курсор перемещается к первому элементу с помощью cursor.moveToFirst(), а затем, прежде чем поймать первый элемент/строку, вы вызываете cursor.moveToNext() в блоке while ниже. И это заставляет вас перейти ко второму элементу/ряду, прежде чем вы сможете добавить первый в адаптер.

if (cursor.moveToFirst()) {
    while (cursor.moveToNext()) {
        int id = cursor.getInt(0);
        String name = cursor.getString(1);
        String open = cursor.getString(2);
        String close = cursor.getString(3);
        byte[] image = cursor.getBlob(4);

        canteenRecordDetailsArrayList.add(new CanteenRecordDetails(id, name, open, close, image));
        canteenAdapter = new CanteenAdapter(getActivity(), canteenRecordDetailsArrayList);
        canteenAdapter.notifyDataSetChanged();
    }
    fchCanGrid.setAdapter(canteenAdapter);
    Log.i(TAG, "Setting adapter to GridView Successful");
} else {
    Log.i(TAG, "Cursor returns null");
}

Решение:

Вам нужно выполнить код внутри блока while перед вызовом cursor.moveToNext()

Используйте do/while вместо while, чтобы повторный код запускался до проверки условия while

if (cursor.moveToFirst()) {
    do {
        int id = cursor.getInt(0);
        String name = cursor.getString(1);
        String open = cursor.getString(2);
        String close = cursor.getString(3);
        byte[] image = cursor.getBlob(4);

        canteenRecordDetailsArrayList.add(new CanteenRecordDetails(id, name, open, close, image));
        canteenAdapter = new CanteenAdapter(getActivity(), canteenRecordDetailsArrayList);
        canteenAdapter.notifyDataSetChanged();
    } while (cursor.moveToNext());
    
    fchCanGrid.setAdapter(canteenAdapter);
    Log.i(TAG, "Setting adapter to GridView Successful");
} else {
    Log.i(TAG, "Cursor returns null");
}