How to create wheel picker for my custom object?

Viewed 4716

I want to let the user choice an element from ArrayList<MyObjectType> via a wheel picker that looks similar to the wheel picker that gets used to pick the day/month/year in the data picker. While the date picker obviously has three variables, I only care about having one.

                                                  Month picker

What's the most straightforward way to implement such a picker?

4 Answers

NumberPicker is provided in Android Widgets. That is what you are looking for.

Solution

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

and in 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

Well, you can simply use NumberPicker as mention here

Or go for a library, WheelView

Here is the implementation with more than 1 picker

Try this way using 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>

OUTPUTS

Normal selection

enter image description here

to let user select first item

enter image description here

to let user select Last item

enter image description here

if list has only one item

enter image description here

To get selected item from this custom picker use this

MyObjectType myObjectType=adapter.getSelectedItem();

You can use custom DialogFragment to display a dialog like the date picker.

so, for example, if your MyObjectType has 3 fields and you want the user to select it.

1- create a 3 recyclerview, each recycler to display a field from your MyObjectType.

2- in your dialog create for loop for your arraylist of your MyObjectType and make 3 custom arraylist, each field has its own arraylist. we will use the arraylist to display the value of the field in recyclerview. in the for loop add each field to its arraylist. e.g arraylistField1.add(MyObjectType.getfield1());

3- create 3 adapters, each adapter for a recyclerview to display the custom arraylist.

4- when user click ok, get the selected value from each adapter.

Related