当我按下复选框时,在ViewHolder之间切换

时间:2019-01-23 18:24:19

标签: java android android-recyclerview

我的片段中有RecycleView适配器和复选框。我希望当我按下复选框时,较旧的视图将发生变化,并且绑定和过滤将有所不同。但是当我运行该应用程序时,它无法正常工作并保持原始模式。您能帮我找到问题吗?

我只是尝试更改视图持有者的详细信息,尚未过滤

public class AvailableDrivesFragment extends Fragment {
public RecyclerView drivesRecyclerView;
public LinearLayout details;
public List<Drive> drives = new ArrayList<>();
public TextView textDetails;
public Button buttonChoose;
IDataBase fb = FactoryDataBase.getDataBase();
private DrivesRecycleViewAdapter adapter;
private Menu menu;
CheckBox checkDistance;
public boolean flag;

Driver driver;

@SuppressLint("ValidFragment")
AvailableDrivesFragment(Driver e) {
    this.driver = e;
}

@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.fragment_available_drives, container, false);
    checkDistance = v.findViewById(R.id.distance_check);
    checkDistance.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (!checkDistance.isChecked()) {
                flag = false;//the flag to recycle view
            }
            if (checkDistance.isChecked()) {
                flag = true;//the flag to recycle view
            }

        }


    });
    textDetails = v.findViewById(R.id.text_details);
    details = v.findViewById(R.id.linear_details);
    details.setVisibility(View.GONE);

    getActivity().setTitle("Available Drives");

    drivesRecyclerView = v.findViewById(R.id.my_list);
    drivesRecyclerView.setHasFixedSize(true);
    drivesRecyclerView.setLayoutManager(new 
    LinearLayoutManager(getActivity()));
    drives = fb.getAvailableDrives();
    adapter = new DrivesRecycleViewAdapter(drives);
    drivesRecyclerView.setAdapter(adapter);
    setHasOptionsMenu(true);


    return v;
}

@Override
public void onDestroy() {
    Firebase_DBManager.stopNotifyToDriveList();
    super.onDestroy();
}

public void checkFlagDistance(View v) {

}


@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.search, menu);

    MenuItem searchItem = menu.findItem(R.id.action_search);
    SearchView searchView = (SearchView) searchItem.getActionView();
    searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            adapter.getFilter().filter(newText);
            return false;
        }
    });
}


public class DrivesRecycleViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable

{
    public List<Drive> drives2;
    public List<Drive> drivefull;

    public DrivesRecycleViewAdapter(List<Drive> drives2) {
        this.drives2 = drives2;
        drivefull = new ArrayList<>(drives);

    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = null;
        RecyclerView.ViewHolder viewHolder = null;

        if (!flag) {
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_drive, parent, false);
            viewHolder = new DriveViewHolder1(view);//swich view holder
        } else {
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_drive, parent, false);
            viewHolder = new DriveViewHolder2(view);
        }

        return viewHolder;
    }


    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        Drive drive = drives.get(position);
        if (!flag) {
            DriveViewHolder1 vaultItemHolder1 = (DriveViewHolder1) holder;
            vaultItemHolder1.nameTextView.setText(drive.getName());
      vaultItemHolder1.phoneTextView.setText(drive.getStartAddress());//the change

        } else {
            DriveViewHolder2 vaultItemHolder2 = (DriveViewHolder2) holder;
            vaultItemHolder2.nameTextView.setText(drive.getName());
            vaultItemHolder2.phoneTextView.setText(drive.getEmail());//the change

        }

    }


    @Override
    public int getItemCount() {
        return drives2.size();
    }

    @Override
    public Filter getFilter() {

        return filter;
    }

    public Filter filter = new Filter() {
   //implement filter

            return results;

        }


        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
           //implement publishResults
        }
    };


    //this is the first view holder
    class DriveViewHolder1 extends RecyclerView.ViewHolder {
        TextView phoneTextView;
        TextView nameTextView;


        public DriveViewHolder1(final View itemView) {
            super(itemView);
            phoneTextView = itemView.findViewById(R.id.phone_item_drive);
            nameTextView = itemView.findViewById(R.id.name_item_drive);}



    }

    //this is the other view holder
    class DriveViewHolder2 extends RecyclerView.ViewHolder {
        TextView phoneTextView;
        TextView nameTextView;


        public DriveViewHolder2(final View itemView) {
            super(itemView);
            phoneTextView = itemView.findViewById(R.id.phone_item_drive);
            nameTextView = itemView.findViewById(R.id.name_item_drive);


           }
}

}

1 个答案:

答案 0 :(得分:0)

您的代码中有两个问题。

第一个很简单:单击复选框可以更新flag的值,但是您不会告诉RecyclerView它需要更新其内容:

checkDistance.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        if (!checkDistance.isChecked()) {
            flag = false;//the flag to recycle view
        }
        if (checkDistance.isChecked()) {
            flag = true;//the flag to recycle view
        }
    }
});

可以通过在更新标志后通知适配器来解决此问题。您还可以简化布尔逻辑:

checkDistance.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        flag = checkDistance.isChecked();
        adapter.notifyDataSetChanged();
    }
});

第二个问题更加复杂。问题是您根据ViewHolder的值使用两个不同的flag子类。如果要使用其他类型的ViewHolders,则需要在适配器中实现getItemViewType()方法。

您应确保仅在flag内部检查getItemViewType() ,并在其他任何地方使用此方法的结果(视图类型)。

public class DrivesRecycleViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {

    @Override
    public int getItemViewType(int position) {
        return flag ? 0 : 1;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_drive, parent, false);

        if (viewType == 1) {
            return new DriveViewHolder1(view);
        } else {
            return new DriveViewHolder2(view);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Drive drive = drives.get(position);
        int viewType = getItemViewType(position);

        if (viewType == 1) {
            DriveViewHolder1 vaultItemHolder1 = (DriveViewHolder1) holder;
            vaultItemHolder1.nameTextView.setText(drive.getName());
            vaultItemHolder1.phoneTextView.setText(drive.getStartAddress());//the change
        } else {
            DriveViewHolder2 vaultItemHolder2 = (DriveViewHolder2) holder;
            vaultItemHolder2.nameTextView.setText(drive.getName());
            vaultItemHolder2.phoneTextView.setText(drive.getEmail());//the change
        }
    }

    ...
}