WearableRecyclerView Android Wear OS
Asked Answered
I

1

17

I'm trying to create a menu similar to the default Wear OS one within my app: Wear OS menu

Various other methods are now deprecated, and unfortunately the Android documentation https://developer.android.com/training/wearables/ui/lists seems very incomplete.

I cannot find any good examples to follow so does anyone have a WearableRecyclerView example that could set menu items and icons such as this, and capture the click events?

Thanks

Illinium answered 6/8, 2018 at 21:56 Comment(0)
I
27

I figured it out myself after a few days of trying. It might not be the best but at least it's working. I used vector icons created by Android Studio in the res/drawable directory. For anyone else looking for a solid example:

main_menu.xml:

<android.support.wear.widget.WearableRecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_menu_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical" />

main_menu_item.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/menu_container"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="5dp"
    android:paddingTop="5dp">

    <ImageView
        android:id="@+id/menu_icon"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_centerVertical="true"
        tools:ignore="HardcodedText" />

    <TextView
        android:id="@+id/menu_item"
        android:layout_width="wrap_content"
        android:layout_height="35dp"
        android:layout_centerVertical="true"
        android:layout_toEndOf="@+id/menu_icon"
        android:layout_toRightOf="@+id/menu_icon"
        android:text="Menu Item"
        android:textColor="#000000"
        android:textSize="24sp"
        tools:ignore="HardcodedText" />
</RelativeLayout>

MainMenuActivity.java:

public class MainMenuActivity extends WearableActivity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_menu);
    WearableRecyclerView recyclerView = findViewById(R.id.main_menu_view);
    recyclerView.setHasFixedSize(true);
    recyclerView.setEdgeItemsCenteringEnabled(true);
    recyclerView.setLayoutManager(new WearableLinearLayoutManager(this));

    ArrayList<MenuItem> menuItems = new ArrayList<>();
    menuItems.add(new MenuItem(R.drawable.icon_1, "Item 1"));
    menuItems.add(new MenuItem(R.drawable.icon_2, "Item 2"));
    menuItems.add(new MenuItem(R.drawable.icon_3, "Item 3"));
    menuItems.add(new MenuItem(R.drawable.icon_4, "Item 4"));

    recyclerView.setAdapter(new MainMenuAdapter(this, menuItems, new MainMenuAdapter.AdapterCallback() {
        @Override
        public void onItemClicked(final Integer menuPosition) {
            switch (menuPosition){
                case 0:  action_1(); break;
                case 1:  action_2(); break;
                case 2:  action_3(); break;
                case 3:  action_4(); break;
                default : cancelMenu();
            }
        }
    }));
}

MainMenuAdapter.java:

public class MainMenuAdapter extends RecyclerView.Adapter<MainMenuAdapter.RecyclerViewHolder> {

    private ArrayList<MenuItem> dataSource = new ArrayList<MenuItem>();
    public interface AdapterCallback{
        void onItemClicked(Integer menuPosition);
    }
    private AdapterCallback callback;

    private String drawableIcon;
    private Context context;


    public MainMenuAdapter(Context context, ArrayList<MenuItem> dataArgs, AdapterCallback callback){
        this.context = context;
        this.dataSource = dataArgs;
        this.callback = callback;
    }

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

        RecyclerViewHolder recyclerViewHolder = new RecyclerViewHolder(view);

        return recyclerViewHolder;
    }

    public static class RecyclerViewHolder extends RecyclerView.ViewHolder
    {
        RelativeLayout menuContainer;
        TextView menuItem;
        ImageView menuIcon;

        public RecyclerViewHolder(View view) {
            super(view);
            menuContainer = view.findViewById(R.id.menu_container);
            menuItem = view.findViewById(R.id.menu_item);
            menuIcon = view.findViewById(R.id.menu_icon);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerViewHolder holder, final int position) {
        MenuItem data_provider = dataSource.get(position);

        holder.menuItem.setText(data_provider.getText());
        holder.menuIcon.setImageResource(data_provider.getImage());
        holder.menuContainer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {

                if(callback != null) {
                    callback.onItemClicked(position);
                }
            }
        });
    }

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

class MenuItem {
    private String text;
    private int image;

    public MenuItem(int image, String text) {
        this.image = image;
        this.text = text;
    }

    public String getText() {
        return text;
    }

    public int getImage() {
        return image;
    }
}
Illinium answered 11/8, 2018 at 13:53 Comment(5)
does this code work? I see that you inflate a layout called main_menu_item, but there is no xml called main_menu_itemStocktaking
@Stocktaking It's working in my app yes. My apologies, I incorrectly labelled the file name. I've made the correction now.Illinium
for the main_menu xml, the following worked for me instead: <androidx.wear.widget.WearableRecyclerView ...Toein
the part where you add menu items to the menu in an ArrayList is underlined in red and I don't know why. It tells me to implement methods, but like 10 methods and even then it's still underlined in red. Any ideas?Vite
have you created the MenuItem class?Illinium

© 2022 - 2024 — McMap. All rights reserved.