如何为我的自定义对象创建滚轮选择器?

6

我希望让用户通过一个类似于日期选择器中用于选择日/月/年的滚轮选择器来选择ArrayList<MyObjectType>中的元素。虽然日期选择器显然有三个变量,但我只关心有一个。

                                                  Month picker

什么是实现这样一个选择器最简单的方法?

不是很简单,但你可以创建一个可滚动的Recycler View,并在其上相对顶部创建一些线条或视图,以给出它是一个轮式选择器的概念,否则可以使用一些开源库。 - Shubham AgaRwal
4个回答

8

NumberPicker是Android小部件中提供的。这正是您所需要的。

解决方案

<NumberPicker
    android:id="@+id/numberPicker"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

同时,在Java中

NumberPicker np = findViewById(R.id.numberPicker);
String[] months3char = get3CharMonths();
np.setMaxValue(months3char.length - 1); // important
np.setDisplayedValues(months3char); // custom values

private String[] get3CharMonths() {
    String[] months = new DateFormatSymbols().getMonths();
    String[] months3char = new String[months.length];
    for (int i = 0; i < months.length; i++) {
        String month = months[i];
        months3char[i] = month.length() < 3 ? month : month.substring(0, 3);
    }
    return months3char;
}

Output


2

尝试使用recyclerview这种方式:

Main2Activity

public class Main2Activity extends AppCompatActivity {


    Button btnShowPicker;

    PickerAdapter adapter;
    LinearLayoutManager linearLayoutManager;
    RecyclerView picRecyclerView;

    ArrayList<MyObjectType> arrayList = new ArrayList<>();

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


        btnShowPicker = findViewById(R.id.btnShowPicker);

        btnShowPicker.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showPicker();
            }
        });
    }

    private void showPicker() {

        Dialog pickerDialog = new Dialog(this);


        pickerDialog.setContentView(R.layout.dialog_layout);


        picRecyclerView = pickerDialog.findViewById(R.id.pickerRecyclerView);
        picRecyclerView = pickerDialog.findViewById(R.id.pickerRecyclerView);

        genArray();

        linearLayoutManager = new LinearLayoutManager(this);
        picRecyclerView.setLayoutManager(linearLayoutManager);
        picRecyclerView.setHasFixedSize(true);
        picRecyclerView.setLayoutManager(linearLayoutManager);



        adapter = new PickerAdapter(Main2Activity.this, arrayList);
        picRecyclerView.setAdapter(adapter);
        picRecyclerView.smoothScrollToPosition(3);


        picRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                int firstItem = linearLayoutManager.findFirstCompletelyVisibleItemPosition();
                int lastItem = linearLayoutManager.findLastCompletelyVisibleItemPosition();

                if (arrayList.size() == 1) {
                    adapter.setSelecteditem(0);
                } else if (lastItem == arrayList.size() - 1) {
                    adapter.setSelecteditem(arrayList.size() - 2);
                } else {
                    adapter.setSelecteditem(firstItem + 1);
                }


            }
        });


        pickerDialog.show();

    }

    private void genArray() {

        // add first dummy item to first position let user select first item
        arrayList.add(new MyObjectType("", 0));

        arrayList.add(new MyObjectType("Jan", 1));
        arrayList.add(new MyObjectType("Feb", 2));
        arrayList.add(new MyObjectType("Mar", 3));
        arrayList.add(new MyObjectType("Apr", 4));
        arrayList.add(new MyObjectType("May", 5));
        arrayList.add(new MyObjectType("Jun", 6));
        arrayList.add(new MyObjectType("Jul", 7));
        arrayList.add(new MyObjectType("Aug", 8));
        arrayList.add(new MyObjectType("Sep", 9));
        arrayList.add(new MyObjectType("Oct", 10));
        arrayList.add(new MyObjectType("Nov", 11));
        arrayList.add(new MyObjectType("Des", 12));
        // add first dummy item to last position let user select last item
        arrayList.add(new MyObjectType("", 0));
    }


}

layout.activity_main2

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:gravity="center"
    tools:context=".Main2Activity">

    <Button
        android:layout_width="match_parent"
        android:text="Show Picker"
        android:id="@+id/btnShowPicker"
        android:layout_height="wrap_content" />


</LinearLayout>

PickerAdapter

public class PickerAdapter extends RecyclerView.Adapter<PickerAdapter.ViewHolder> {

    private Context context;
    private ArrayList<MyObjectType> arrayList= new ArrayList<>();

    private int selectedItem = -1;
    int pos=0;

    PickerAdapter(Context context, ArrayList<MyObjectType> arrayList) {
        this.context = context;
        this.arrayList = arrayList;
    }

    @NonNull
    @Override
    public PickerAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.custom_picker_layout,parent,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull PickerAdapter.ViewHolder holder, int position) {

        holder.tvValue.setText(arrayList.get(position).getTitle());
        if (position == selectedItem) {
            Log.d("CenterPosition", "center" + position);
            holder.tvValue.setBackgroundResource(R.drawable.tv_bg);

        } else {
            holder.tvValue.setBackgroundColor(Color.BLACK);
        }
    }

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

    public MyObjectType getSelectedItem() {
        return arrayList.get(selectedItem);
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView tvValue;
        public ViewHolder(View itemView) {
            super(itemView);

            tvValue=itemView.findViewById(R.id.tvValue);

            tvValue.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(context, "Clicked : "+arrayList.get(getAdapterPosition()).getTitle(), Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
    public void setSelecteditem(int selecteditem) {
        Log.d("POSITION",String.valueOf(selecteditem));
        this.selectedItem = selecteditem;
        notifyDataSetChanged();
    }
}

layout.custom_picker_layout

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

    <TextView
        android:id="@+id/tvValue"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:background="@drawable/tv_bg"
        android:padding="10dp"
        android:textColor="#FFFFFF" />

</LinearLayout>

android:background="@drawable/tv_bg"

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#08bfdf" />
        </shape>
    </item>
    <item android:bottom="2dp"  android:top="2dp" >

        <shape android:shape="rectangle">
            <solid android:color="#000000" />
        </shape>
    </item>
</layer-list>

输出结果

常规选择

enter image description here

让用户选择第一个项目

enter image description here

让用户选择最后一个项目

enter image description here

如果列表只有一个项目

enter image description here

要从此自定义选择器中获取所选项目,请使用以下方法

MyObjectType myObjectType=adapter.getSelectedItem();

2

你可以简单地使用NumberPicker,就像这里提到的那样。

或者使用库,比如WheelView

这里有一个实现多个选择器的示例。


0

您可以使用自定义的DialogFragment来显示像日期选择器一样的对话框。

例如,如果您的MyObjectType有3个字段,并且您希望用户进行选择。

1- 创建3个RecyclerView,每个RecyclerView用于显示MyObjectType的一个字段。

2- 在您的对话框中,为MyObjectType的arraylist创建for循环,并创建3个自定义arraylist,每个字段都有自己的arraylist。我们将使用arraylist来在RecyclerView中显示字段的值。在for循环中,将每个字段添加到其arraylist中。例如:arraylistField1.add(MyObjectType.getfield1());

3- 创建3个适配器,每个适配器用于RecyclerView以显示自定义arraylist。

4- 当用户单击确定时,从每个适配器获取所选值。


我不关心对话框,我只关心有一个单一的选择器。我不确定您如何建议recyclerview管理对象的选择以及如何使其上下方的元素显示为灰色。 - Christian
很抱歉,我需要与您聊天以便向您提供步骤。在您获得步骤后,我们可以更新答案。 - Momen Zaqout
请在Skype上给我发送消息 momen-zaq@outlook.com - Momen Zaqout
使用数字选择器 https://developer.android.com/reference/android/widget/NumberPicker - Jay Pandya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接