Первый элемент появляется в конце списка в адаптере GridView - PullRequest
1 голос
/ 03 мая 2020

Итак, у меня есть DashboardFragment с отображением элементов в сетке, при нажатии последнего элемента в сетке он открывает новое действие для добавления новой категории в базу данных, после добавления ее в базу данных это действие закрывается и сетка в DashboardFragment должна обновиться с новым элементом в конце сетки. Вот код, который я придумал, проблема в том, что всякий раз, когда я добавляю новую категорию, обновления сетки, но с первым элементом списка в конце сетки. Когда я перезапускаю приложение, в конце появляется новый элемент, и все отображается так, как нужно, поэтому он правильно добавляет элемент в базу данных. В отладчике оба списка (один в адаптере и один в основном классе) одинаковы и с новым элементом в конце. Я потратил полдня на поиски решения, но не могу найти причину этой проблемы.


public class DashboardFragment extends Fragment {

    private DashboardViewModel dashboardViewModel;
    List<Category> categories = new ArrayList<>();
    PieChart chart;

    CategoryAdapter adapter;

    DBHelper dbHelper;
    SQLiteDatabase database;


    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        dashboardViewModel = ViewModelProviders.of(this).get(DashboardViewModel.class);
        View root = inflater.inflate(R.layout.fragment_dashboard, container, false);
        setHasOptionsMenu(true);

        //-----Database
        dbHelper = new DBHelper(super.getContext());
        //-----Categories
        ParseCategories();
        final ExpandableHeightGridView gridView = (ExpandableHeightGridView) root.findViewById(R.id.category_grid);
        adapter = new CategoryAdapter(root.getContext(), categories);
        gridView.setAdapter(adapter);
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (position == categories.size() - 1) {
                    startActivityForResult(new Intent(DashboardFragment.super.getContext(), CategoryCreation.class),1);

                }
            }
        });
        gridView.setExpanded(true);
        //-----Chart
        chart = (PieChart) root.findViewById(R.id.chart);
        setupPieChart();
        return root;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode==1){
            ParseCategories();
            adapter.updateCategoryList(categories);
        }
    }

    public void ParseCategories() {
        categories.clear();
        database = dbHelper.getWritableDatabase();
        Cursor c = database.rawQuery("select * from categories", null);
        c.moveToFirst();
        for (int i = 0; i < c.getCount(); i++) {
            int id = c.getInt(c.getColumnIndex("_id"));
            String name = c.getString(c.getColumnIndex("name"));
            double amount = c.getDouble(c.getColumnIndex("amount"));
            int imageId = c.getInt(c.getColumnIndex("iconId"));
            categories.add(new Category(id, name, amount, imageId));
            c.moveToNext();
        }
        categories.add(new Category(-1, "Add", -1, R.drawable.add_category_icon));
        c.close();
        database.close();
    }

    public class CategoryAdapter extends BaseAdapter {
        private Context context;
        private List<Category> categories;

        public CategoryAdapter(Context context, List<Category> cats) {
            this.context = context;
            this.categories = cats;
        }

        public View getView(int position, View convertView, ViewGroup parent) {

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            View gridView;

            if (convertView == null) {

                gridView = new View(context);

                gridView = inflater.inflate(R.layout.dashboard_category_item, null);

                TextView nameView = (TextView) gridView.findViewById(R.id.category_name);
                ImageView imageView = (ImageView) gridView.findViewById(R.id.grid_item_image);
                TextView amountView = (TextView) gridView.findViewById(R.id.category_amount);

                nameView.setText(categories.get(position).getName());
                imageView.setImageResource(categories.get(position).getIconId());
                if (categories.get(position).getAmount() >= 0) {
                    amountView.setText("$" + categories.get(position).getAmount());
                } else {
                    amountView.setText("");
                }

            } else {
                gridView = (View) convertView;
            }

            return gridView;
        }

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

        @Override
        public Object getItem(int position) {
            return null;
        }

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

        public void updateCategoryList(List<Category> newlist) {
            this.notifyDataSetChanged();
        }
    }
}

1 Ответ

1 голос
/ 04 мая 2020

Попробуйте:

    public View getView(int position, View convertView, ViewGroup parent) {

        View gridView;
        if (convertView == null) {
            gridView = new View(context);
            LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            gridView = inflater.inflate(R.layout.dashboard_category_item, null);
        } else {
            gridView = (View) convertView;
        }

        TextView nameView = (TextView) gridView.findViewById(R.id.category_name);
        ImageView imageView = (ImageView) gridView.findViewById(R.id.grid_item_image);
        TextView amountView = (TextView) gridView.findViewById(R.id.category_amount);

        nameView.setText(categories.get(position).getName());
        imageView.setImageResource(categories.get(position).getIconId());
        if (categories.get(position).getAmount() >= 0) {
            amountView.setText("$" + categories.get(position).getAmount());
        } else {
            amountView.setText("");
        }

        return gridView;
    }

Объяснение: Для лучшего использования памяти и повышения эффективности adpater предназначен для повторного использования / повторного использования представлений элементов . Одной из ситуаций является прокрутка, некоторые элементы исчезают, и адаптер получает исчезнувшие представления из аргумента convertView , который можно использовать для новых элементов. Но эти convertViews содержат старые данные, поэтому они должны быть заполнены новыми данными. Аналогичная ситуация с notifyDataSetChanged (). Поэтому коды для заполнения данных в представлении элемента должны быть после if (convertView == null) {...}else{...}.

...