首页 > 解决方案 > 如何从复选框的列表视图中将变量设置为真/假?

问题描述

我创建了一个带有自定义适配器的列表视图,它允许我拥有一个项目列表,每个项目旁边都有复选框。

因此,我想查看列表中相应项目的复选框,看看它是否被选中,如果是,则将 boolean Whisky = false 的值设置为 true,以此类推其他布尔值。

我很可能在错误的类或 xml 文件中有代码,我一直在尝试拼凑我在互联网上找到的东西。我是android studio的新手,所以证明非常困难。不过,我确实有大约一年的 Java 经验。我在 Eclipse 上的一个工作程序中编写了我的所有代码,我只是想弄清楚如何将它实现到一个工作应用程序中。

提前致谢。

customAdapter.java

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;

import java.util.ArrayList;

public class customAdapter extends BaseAdapter {
private ArrayList<String> list = new ArrayList<String>();
private Context context;

public customAdapter(ArrayList<String> list, Context context) {
    this.list = list;
    this.context = context;
}

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

@Override
public Object getItem(int pos) {

    return list.get(pos);
}
public void setChecked(boolean isChecked){

}


@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    View view = convertView;
    if (view == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.activity2_listview, null);
    }

    //Handle TextView and display string from your list
    TextView label = (TextView)view.findViewById(R.id.label);
    label.setText(list.get(position));

    //Handle buttons and add onClickListeners
    CheckBox callchkbox = (CheckBox) view.findViewById(R.id.cb);



    callchkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            //update isChecked value to model class of list at current position
            list.get(position).setChecked(isChecked);
        }
    });
    return view;
}

public long getItemId(int position) {
    // TODO Auto-generated method stub
    return position;
}

Main2Activity.java

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.Arrays;
import android.widget.CheckBox;

public class Main2Activity extends AppCompatActivity {


boolean Whiskey, Bourbon, Rum, Gin, Vodka, Tequila = false;



String [] userIngredients = {"Whiskey", "Bourbon", "Rum", "Gin", "Vodka", "Tequila", "Club Soda", "Lemon-Lime Soda",
"Ginger ale", "Cola", "Still mineral water", "Tonic Water", "Orange Juice", "Cranberry Juice", "Grapefruit Juice",
"Tomato Juice", "Cream or Half and Half", "Milk", "Ginger Beer", "PineApple Juice", "Lemons", "Limes", "Oranges"};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);

    ListView listView = (ListView) findViewById(R.id.userIngredients);

    ArrayList<String> list = new ArrayList<String>(Arrays.asList(userIngredients));


    listView.setAdapter(new customAdapter(list, Main2Activity.this));

}


        }

activity_main2.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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=".Main2Activity"
android:id="@+id/linearLayout">

<ListView
    android:layout_width="419dp"
    android:layout_height="558dp"
    android:id="@+id/userIngredients"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/textView2"
    tools:layout_conversion_absoluteHeight="731dp"
    tools:layout_conversion_absoluteWidth="411dp" />

<TextView
    android:id="@+id/textView2"
    android:layout_width="374dp"
    android:layout_height="60dp"
    android:layout_marginStart="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginTop="16dp"
    android:layout_marginEnd="8dp"
    android:layout_marginRight="8dp"
    android:text="Check Your Ingredients"
    android:textSize="24sp"
    app:fontFamily="@font/cinzel"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />


</android.support.constraint.ConstraintLayout>

activity2_listview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:id="@+id/label"
    android:layout_width="323dp"
    android:layout_height="wrap_content"
    android:layout_marginLeft="20dp"
    android:text="ingredient"
    android:textSize="20sp" />

<CheckBox
    android:id="@+id/cb"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />


</LinearLayout>

标签: javaandroidandroid-studiolistviewcheckbox

解决方案


我认为您也可以使用 BaseAdapter 来做到这一点,但我建议改用 RecyclerView。

我使用 support-v4 和 recyclerview-v7 库如下:(确保您没有开发 AndroidX - 检查整个项目的 gradle.properties。它非常相似,但使用其他库。)

构建.gradle

   android {
    compileSdkVersion 28
    buildToolsVersion '28.0.3'
  ...
    dependencies {
     implementation 'com.android.support:appcompat-v7:28.0.0'
     implementation 'com.android.support:support-v4:28.0.0'
     implementation 'com.android.support:design:28.0.0'
     implementation 'com.android.support.constraint:constraint-layout:1.1.3'
     implementation 'com.android.support:recyclerview-v7:28.0.0'
   ...

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.widget.RelativeLayout
    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">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Check Your Ingredients"
        android:textAlignment="center" />

    <android.support.v7.widget.RecyclerView

        android:id="@+id/recycler_chooser"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" >
    </android.support.v7.widget.RecyclerView>

</android.widget.RelativeLayout>

在 activity2_listview 中,您可能想要对 xml 进行更多设计。现在看起来很基础。

activity2_listview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/listviewtextlabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:text="ingredient"
        android:textSize="20sp" />

    <CheckBox
        android:id="@+id/listviewcheckbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />


</LinearLayout>

在主类中,我们为自定义onItemAction函数实现了一个回调监听器。我们通过监听adapter.setActionListener(this);器并将适配器添加到 RecyclerViewer。

MainActivity.java

public class MainActivity extends AppCompatActivity implements CustomAdapter.ItemActionListener {

    boolean Whiskey, Bourbon, Rum, Gin, Vodka, Tequila = false;



    String [] userIngredients = {"Whiskey", "Bourbon", "Rum", "Gin", "Vodka", "Tequila", "Club Soda", "Lemon-Lime Soda",
            "Ginger ale", "Cola", "Still mineral water", "Tonic Water", "Orange Juice", "Cranberry Juice", "Grapefruit Juice",
            "Tomato Juice", "Cream or Half and Half", "Milk", "Ginger Beer", "PineApple Juice", "Lemons", "Limes", "Oranges"};

    CustomAdapter adapter;
    RecyclerView.LayoutManager layoutManager;
    RecyclerView recyclerListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            recyclerListView = (RecyclerView) findViewById(R.id.recycler_chooser);

            ArrayList<String> list = new ArrayList<>();
            list.addAll(Arrays.asList(userIngredients));

            // use this setting to improve performance if you know that changes
            // in content do not change the layout size of the RecyclerView
            recyclerListView.setHasFixedSize(false);

            layoutManager = new LinearLayoutManager(this);
            recyclerListView.setLayoutManager(layoutManager);

            System.out.println("list.size() " + list.size());

            adapter = new CustomAdapter(list,MainActivity.this);
            adapter.setActionListener(this);
            recyclerListView.setAdapter(adapter);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    // callback listener for your items
    @Override
    public void onItemAction(View view, CustomAdapter.CustomActions customAction, int position) {
        final String itemName = adapter.getItem(position);
        System.out.println(customAction + ": You clicked " + itemName + " on row number " + position);

        switch(itemName){
            case "Whiskey":
                if(customAction== CustomAdapter.CustomActions.CHECK){
                    Whiskey=true;
                }
                else{
                    Whiskey=false;
                }
                System.out.println("Whiskey set to: " + Whiskey);
                break;
            case "Bourbon":
                if(customAction== CustomAdapter.CustomActions.CHECK){
                    Bourbon=true;
                }
                else{
                    Bourbon=false;
                }
                System.out.println("Bourbon set to: " + Bourbon);
                break;
                //case xyz
                  //  and so on
            default:
                System.out.println("Not programmed yet: " + itemName);
        }
    }
}

如上所述,我删除了 BaseAdapter 并将其替换为 RecyclerView。我们必须实现一个自定义 ViewHolder 类,它包含 RecyclerViewList 中的每一行。在 ViewHolder 中,只要发生复选框更改事件,我们就可以调用侦听器上的方法。

CustomAdapter.java

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;

import java.util.ArrayList;

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> {

    //------ helper class for the viewholder
    enum CustomActions{
        CHECK,UNCHECK
    }
    // Provide a reference to the views for each row
    public class CustomViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView mTextView;
        public CheckBox mCheckBox;

        public CustomViewHolder(View v) {
            super(v);
            // the view element v is the whole linear layout element
            CheckBox.OnCheckedChangeListener checkboxListenerForOneEntry =  new CheckBox.OnCheckedChangeListener(){

                @Override
                public void onCheckedChanged(CompoundButton view, boolean isChecked) {
                    if (mItemActionListener != null) {
                        if(isChecked){
                            // this compoundbutton view element will be the checkbox
                            mItemActionListener.onItemAction(view, CustomActions.CHECK, getAdapterPosition());
                        }else{
                            mItemActionListener.onItemAction(view, CustomActions.UNCHECK, getAdapterPosition());
                        }
                    }
                }
            };
            mTextView = v.findViewById(R.id.listviewtextlabel);
            mCheckBox = v.findViewById(R.id.listviewcheckbox);
            mCheckBox.setOnCheckedChangeListener(checkboxListenerForOneEntry);
        }
    }
    //------

    private ArrayList<String> list;
    private Context context;
    private LayoutInflater mInflater;
    private ItemActionListener  mItemActionListener;

    public CustomAdapter(ArrayList<String> list, Context context) {
        this.list = list;
        this.context = context;
        this.mInflater = LayoutInflater.from(this.context);
    }

    // allows clicks events to be caught
    void setActionListener(ItemActionListener itemActionListener) {
        this.mItemActionListener = itemActionListener;
    }

    // parent activity will implement this method to respond to click events
    public interface ItemActionListener {
        void onItemAction(View view, CustomActions customAction, int position);
    }

    // Create new views (invoked by the layout manager)
    @Override
    public CustomViewHolder onCreateViewHolder(ViewGroup parent,
                                               int viewType) {
        // create a new view
        View v = mInflater.inflate(R.layout.activity2_listview, parent, false);
        return new CustomViewHolder(v);
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(CustomViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        holder.mTextView.setText(list.get(position));
    }

    @Override // Return the size of your dataset (invoked by the layout manager)
    public int getItemCount() {
        return getCount();
    }

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

    public String getItem(int pos) {
        return list.get(pos);
    }
}

随意使用代码。

有关 RecyclerView 的更多信息,请参阅谷歌文档:https ://developer.android.com/guide/topics/ui/layout/recyclerview


推荐阅读