Search code examples
androidandroid-listview

listview item is not displaying the assigned value in getview method of custom adapter


I ran into a problem and still don't know how to get out. I made a listview with a custom adapter for it. I also implemented a searchview which will update the listview everytime I type in a character. But the problem is that the listview is not showing the correct results. I put some checkpoints in getView method of the custom adapter to check if the values which will be displayed are right or not and they're all right.

enter image description here

I have two items, let's call them HD03 and HD02 as you can see their name on the top left corner of each item.

when I type in the search bar 02, the result must be item HD02 but I got item HD03 instead. Although, the value I checked in the getView method using debugger was HD02

enter image description here

I think I made a silly mistake somewhere but I can't find it. Thank you for your time ! Here're my fragment and my adapter code.

Fragment

public class DashboardFragment extends Fragment {

    private DashboardViewModel dashboardViewModel;
    private ListView listViewContract;
    private SearchView contractSearchView;
    private ContractAdapter productListAdapter;

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

        initView(root);

        return root;
    }

    private void initView(View view) {
        listViewContract = view.findViewById(R.id.contract_list);
        listViewContract.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                listViewProduct_onItemClick(adapterView, view, i, l);
            }
        });

        loadData();

        contractSearchView = view.findViewById(R.id.search_bar);
        contractSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                DashboardFragment.this.productListAdapter.getFilter().filter(query);

                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                DashboardFragment.this.productListAdapter.getFilter().filter(newText);

                return false;
            }
        });
    }

    private void loadData() {
        List<Contract> products = new ArrayList<Contract>();
        products.add(new Contract("p03", "Name 1", "4", "Mới", "HD03" ));
        products.add(new Contract("p02", "Name 2", "5", "Mới", "HD02"));
        productListAdapter = new ContractAdapter(getContext(), products);
        listViewContract.setAdapter(productListAdapter);
    }

    private void listViewProduct_onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//        Product product = (Product) adapterView.getItemAtPosition(i);
//        Toast.makeText(getApplicationContext(), product.getName(), Toast.LENGTH_LONG).show();
    }
}

Adapter

public class ContractAdapter extends BaseAdapter implements Filterable {

    private Context context;
    private List<Contract> products;
    private List<Contract> filteredData;
    private ItemFilter itemFilter = new ItemFilter();

    public ContractAdapter(Context context, List<Contract> products){
        this.context = context;
        this.products = products;
        this.filteredData = products;
    }

    @NonNull
    @Override
    public View getView(int position, View view, ViewGroup parent) {
        ViewHolder viewHolder;
        if (view == null) {
            viewHolder = new ViewHolder();
            view = LayoutInflater.from(context).inflate(R.layout.phan_anh_cardview, parent, false);
            viewHolder.textViewContractName = view.findViewById(R.id.ten_hd);
            viewHolder.textViewCustomerName = view.findViewById(R.id.ten_dt);
            viewHolder.textViewEmployeeName = view.findViewById(R.id.ten_nv);
            viewHolder.textViewId = view.findViewById(R.id.ma_hd);
            viewHolder.buttonStatus = view.findViewById(R.id.report_status);
            view.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) view.getTag();
        }
        Contract product = filteredData.get(position);
        viewHolder.textViewContractName.setText(product.getName());
        viewHolder.textViewEmployeeName.setText(product.getNhanvien());
        viewHolder.textViewCustomerName.setText(product.getCustomer());
        viewHolder.textViewId.setText(product.get_id());
        viewHolder.buttonStatus.setText(product.getStatus());

        Log.i("view", viewHolder.textViewId.getText().toString());

        return view;
    }

    public int getCount(){
        return filteredData.size();
    }

    public Contract getItem(int position) {
        return filteredData.get(position);
    }

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

    @NonNull
    @Override
    public Filter getFilter() {
        return itemFilter;
//        return super.getFilter();
    }

    private static class ViewHolder {
        public static TextView textViewContractName;
        public static TextView textViewCustomerName;
        public static TextView textViewEmployeeName;
        public static TextView textViewId;
        public static Button buttonStatus;
    }

    private class ItemFilter extends Filter{

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            String query = constraint.toString();

            FilterResults results = new FilterResults();
            List<Contract> originalData = products;
            int count = originalData.size();
            List<Contract> nList = new ArrayList<>();

            for (Contract contract : originalData) {
                if(contract.get_id().contains(query) || contract.getName().contains(query) || contract.getCustomer().contains(query)){
                    nList.add(contract);
                }
            }

            results.values = nList;
            results.count = nList.size();

            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            filteredData = (List<Contract>) results.values;
            notifyDataSetChanged();
        }
    }
}

fragment_dashboard.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.dashboard.DashboardFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/tag_spinner_constraint"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <SearchView
            android:id="@+id/search_bar"
            android:layout_width="match_parent"
            android:layout_height="45dp"
            android:iconifiedByDefault="false"
            app:layout_constraintEnd_toEndOf="@id/tag_spinner_constraint"
            app:layout_constraintStart_toStartOf="@id/tag_spinner_constraint"
            app:layout_constraintTop_toTopOf="@id/tag_spinner_constraint" />

        <HorizontalScrollView
            android:id="@+id/filter_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scrollbars="none"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/search_bar">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <androidx.appcompat.widget.AppCompatButton
                    android:id="@+id/empty_rooms_btn"
                    android:layout_width="99dp"
                    android:layout_height="34dp"
                    android:layout_marginStart="5dp"
                    android:layout_marginLeft="5dp"
                    android:layout_marginTop="4dp"
                    android:background="@drawable/rounded_button"
                    android:text="Phòng trống"
                    android:textSize="12sp"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@+id/floor_spinner" />

                <androidx.appcompat.widget.AppCompatButton
                    android:id="@+id/not_full_rooms_btn"
                    android:layout_width="wrap_content"
                    android:layout_height="34dp"
                    android:layout_marginStart="12dp"
                    android:layout_marginLeft="12dp"
                    android:layout_marginTop="4dp"
                    android:background="@drawable/rounded_button"
                    android:text="Phòng ghép"
                    android:textSize="12sp"
                    app:layout_constraintStart_toEndOf="@+id/empty_rooms_btn"
                    app:layout_constraintTop_toBottomOf="@+id/floor_spinner" />

                <androidx.appcompat.widget.AppCompatButton
                    android:id="@+id/full_rooms_btn"
                    android:layout_width="105dp"
                    android:layout_height="34dp"
                    android:layout_marginLeft="10dp"
                    android:layout_marginTop="4dp"
                    android:background="@drawable/rounded_button"
                    android:text="Phòng đã đầy"
                    android:textSize="12sp"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toEndOf="@+id/not_full_rooms_btn"
                    app:layout_constraintTop_toBottomOf="@+id/floor_spinner" />

                <androidx.appcompat.widget.AppCompatButton
                    android:id="@+id/all_rooms_btn"
                    android:layout_width="wrap_content"
                    android:layout_height="34dp"
                    android:layout_marginLeft="10dp"
                    android:layout_marginTop="4dp"
                    android:background="@drawable/rounded_button"
                    android:text="Tất cả"
                    android:textSize="12sp" />

            </LinearLayout>

        </HorizontalScrollView>

    </androidx.constraintlayout.widget.ConstraintLayout>


    <ListView
        android:id="@+id/contract_list"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="2dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tag_spinner_constraint">


    </ListView>

</androidx.constraintlayout.widget.ConstraintLayout>

phan_anh_cardview.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:padding="8dp">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="162dp"
            android:layout_marginTop="5dp"
            android:padding="6dp">

            <androidx.appcompat.widget.AppCompatButton
                android:id="@+id/report_status"
                android:layout_width="68dp"
                android:layout_height="15dp"
                android:background="@drawable/rounded_button"
                android:text="Mới"
                android:textSize="10sp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/ma_hd"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="18sp"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/ten_hd"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="30sp"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/ma_hd" />

            <TextView
                android:id="@+id/ten_dt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20sp"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/ten_hd" />

            <TextView
                android:id="@+id/ten_nv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20sp"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/ten_dt" />

        </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.cardview.widget.CardView>

</androidx.constraintlayout.widget.ConstraintLayout>

rounded_button.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/cardview_dark_background" />
    <corners android:bottomRightRadius="30dp"
        android:bottomLeftRadius="30dp"
        android:topRightRadius="30dp"
        android:topLeftRadius="30dp"/>
</shape>

Solution

  • I found error in your code. You shouldn't use static members in ViewHolder. So please replace ViewHolder code as following.

    ContractAdapter.java

    ..............
    
    private static class ViewHolder {
        public TextView textViewContractName;
        public TextView textViewCustomerName;
        public TextView textViewEmployeeName;
        public TextView textViewId;
        public Button buttonStatus;
    }
    
    ...............
    

    If so, it will be working.