我有一个使用自定义适配器填充了checkedtextview的列表视图,我遇到的问题是,例如,当我在列表视图中选中一个复选框或另一个复选框时,现在已经相当了解列表的概念视图以及视图的回收方式,那么我在这里做错了什么?
我遇到的另一个问题是,滚动时复选框的位置不断变化
我已经尝试了多种解决方案并一直在尝试,对于了解此问题的任何帮助,我们都将不胜感激
这是checkedtextview xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<CheckedTextView
android:id="@+id/checkedTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:checked="false"
android:drawableLeft="?android:attr/listChoiceIndicatorMultiple"
android:gravity="center"
android:paddingBottom="@dimen/virtical_padding"
android:textAppearance="?android:textAppearanceLarge"
tools:text="Service 1" />
<Button
android:id="@+id/plus_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/check_box_list_margin"
android:layout_marginLeft="@dimen/check_box_list_margin"
android:focusable="false"
android:text="@string/plus"
android:textColor="#000"
android:visibility="invisible" />
<TextView
android:id="@+id/quantity_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:text="@string/quantity_default"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#000"
android:visibility="invisible" />
<Button
android:id="@+id/minus_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:text="@string/minus"
android:textColor="#000"
android:visibility="invisible" />
</LinearLayout>
这是OnItemClickListener的代码
mServiceListView.setOnItemClickListener( new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//find the checkedTextView inside the relative view
ctv = (CheckedTextView) view.findViewById( R.id.checkedTextView );
mServiceQuantity = (TextView) view.findViewById( R.id.quantity_tv );
mMinusBtn = ( Button) view.findViewById( R.id.minus_btn );
mPlusBtn = (Button) view.findViewById( R.id.plus_btn );
((CheckedTextView) ctv).toggle();
Service service = (Service) parent.getItemAtPosition(position);
if (ctv.isChecked()) {
selectedServices.add(service.getServiceNum());
//make the quantity option visible
mMinusBtn.setVisibility( View.VISIBLE );
mPlusBtn.setVisibility( View.VISIBLE );
mServiceQuantity.setVisibility( View.VISIBLE );
} else {
//remove the service and quantity from table
selectedServices.remove( service.getServiceNum() );
selectedServicesHash.remove( service.getServiceNum() );
//the quantity option will be invisible
mMinusBtn.setVisibility( View.INVISIBLE );
mPlusBtn.setVisibility( View.INVISIBLE );
mServiceQuantity.setVisibility( View.INVISIBLE );
}
}
} );
这是自定义适配器的代码
package com.example.android.bookkeepingapp;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CheckedTextView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import org.w3c.dom.Text;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;
public class ServiceAdapterCheckBox extends ArrayAdapter<Service> {
private Hashtable<String, Integer> selectedServicesHash;
private Set<String> serviceNums;
public ServiceAdapterCheckBox(@NonNull Context context, int resource, List<Service> objects
, Hashtable<String, Integer> selectedServiceHash) {
super( context, resource, objects );
this.selectedServicesHash = selectedServiceHash;
}
public void setSelectedServicesHash(Hashtable<String, Integer> selectedServices) {
this.selectedServicesHash = selectedServices;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
//Find the current object
Service service = getItem(position);
//put all the services name of the hashtable in a list
serviceNums= selectedServicesHash.keySet();
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(getContext()).inflate(R.layout.service_item_check_box,
parent, false);
holder.textCheckBox = (CheckedTextView) convertView.findViewById(R.id.checkedTextView);
holder.minBtn = (Button) convertView.findViewById( R.id.minus_btn );
holder.plusBtn = (Button) convertView.findViewById( R.id.plus_btn );
holder.quantityTv = (TextView) convertView.findViewById( R.id.quantity_tv );
convertView.setTag(holder);
}
else {
// the getTag returns the viewHolder object set as a tag to the view
holder = (ViewHolder)convertView.getTag();
}
//supply the textViews with the correct data
assert service != null;
holder.textCheckBox.setText( service.getServiceName() );
//set the quantity value set by the user
holder.plusBtn.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View view) {
//holder.plusBtn.setFocusable( true );
int quantityValue = Integer.parseInt(holder.quantityTv.getText().toString());
quantityValue++;
holder.quantityTv.setText( String.valueOf( quantityValue ) );
}
} );
holder.minBtn.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View view) {
//holder.plusBtn.setFocusable( true );
int quantityValue = Integer.parseInt(holder.quantityTv.getText().toString());
if(quantityValue == 1){
quantityValue = 1;
}
else {
quantityValue--;
}
holder.quantityTv.setText( String.valueOf( quantityValue ) );
}
} );
//if the there are services in the hash table
if(serviceNums.size() != 0) {
Log.v(this.getContext().toString(), "there are services selected");
//put all the services name of the hashtable in a list
for (String s : serviceNums) {
if (service.getServiceNum().equals( s )) {
//set the check text with the current position to true
//holder.textCheckBox.setChecked( true );
//set the quantity text box to the correct value set by the user
//holder.quantityTv.setText(selectedServicesHash.get(s));
//set the quantity selectors to visible
holder.plusBtn.setVisibility( View.VISIBLE );
holder.minBtn.setVisibility( View.VISIBLE );
holder.quantityTv.setVisibility( View.VISIBLE );
}
}
}
else{
Log.v(this.getContext().toString(), "no the list is empty");
//set the quantity text box to the correct value set by the user
holder.quantityTv.setText("1");
}
return convertView;
}
public Hashtable<String, Integer> getSelectedServicesHash() {
return selectedServicesHash;
}
/**
* customizable toast
*
* @param message
*/
private void toastMessage(String message) {
Toast.makeText( getContext(), message, Toast.LENGTH_SHORT ).show();
}
private class ViewHolder {
protected CheckedTextView textCheckBox;
protected Button plusBtn;
protected Button minBtn;
protected TextView quantityTv;
}
}
我想要做的就是获取具有正确位置的正确复选框 谢谢...
答案 0 :(得分:1)
由于视图是在ListView中回收的,因此必须将视图状态更新为适配器代码中的状态。否则,视图将仅具有已重用的旧视图的选中状态。
因此,除了更新视图上的文本外,您还需要设置其选中状态。
//supply the textViews with the correct data
assert service != null;
holder.textCheckBox.setText( service.getServiceName() );
// ALSO UPDATE THE CHECKED STATE - FROM YOUR POSTED CODE, I ASSUME IT SHOULD BE
// CHECKED IF IT APPEARS IN THE "selectedServices" list
holder.textCheckBox.setChecked(selectedServices.contains(service));