Nicky HFE
Nicky HFE

Reputation: 143

Android : onOptionsItemSelected() does not respond

I'm not sure if this is a duplicate or not, the possible remedy I've tried doesn't work. (Will be mentioned below)

I'm currently using Theme.AppCompat.NoActionBar for the project I'm doing and is using android.support.design.widget.AppBarLayout and android.support.design.widget.CollapsingToolbarLayout in tandem with android.support.v7.widget.Toolbar.

The options menu is intended to be apart of the toolbar menu so that

  1. The user may navigate to About activity should they need more information
  2. The user may choose to logout to end their session.

The following are the codes. Those indicated by double asterisk are what I believe to be the important ones in the code for onCreate()

1) VacancyList.java : onCreate()

public class VacancyList extends AppCompatActivity
{
    private final static ArrayList <String> ELEMENTS= new ArrayList<>(Arrays.asList("restaurantID", "restaurantName", "restaurantType", "ST_ASText(restaurantLoc)", "restaurantLot", "restaurantVacancy", "restaurantOwner", "restaurantContact","restaurantEmail"));
    private final static String TAG_RESULT = "result";

    private Toolbar toolBar;
    private RecyclerView recyclVw;
    private RestInfoAdapter adapter;
    private SwipeRefreshLayout refresh;

    private ArrayList<RestInfo> rInf_LIST;

    //Temporary
    private TextView txtVw;

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

        **toolBar = (Toolbar)findViewById(R.id.toolbar);
        toolBar.inflateMenu(R.menu.toolbar_menu);**

        rInf_LIST = new ArrayList<>();

        //AsyncTask calls
        new ListGetterTask(true).execute();

        //Setup Recycler View with the appropriate adapter and layout.
        recyclVw = (RecyclerView)findViewById(R.id.recyclerView);
        adapter = new RestInfoAdapter(this, rInf_LIST);
        GridLayoutManager glm = new GridLayoutManager(this, 1);

        recyclVw.setLayoutManager(glm);
        recyclVw.setAdapter(adapter);

        refresh = (SwipeRefreshLayout)findViewById(R.id.refresh);
        refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                new Handler().post(new Runnable() {
                    @Override
                    public void run() {
                        new ListGetterTask(false).execute();
                        Toast.makeText(VacancyList.this, "ListGetter Executed", Toast.LENGTH_SHORT).show();
                        refresh.setRefreshing(false);
                    }
                });
            }
        });
    }

2) VacancyList.java : onCreateOptionsMenu()

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    getMenuInflater().inflate(R.menu.toolbar_menu, menu);
    return true;
}

3) VacancyList.java : onOptionsItemSelected()

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    switch (item.getItemId())
    {
        case R.id.aboutPage:
        {
            startActivity(new Intent(VacancyList.this, About.class));
            return true;
        }
        case R.id.logOut:
        {
            String prefName = getString(R.string.prefName), key0 = getString(R.string.key0), key1 = getString(R.string.key1), key2 = getString(R.string.key2);

            SharedPreferences sharedPref = getSharedPreferences(prefName, Context.MODE_PRIVATE);
            SharedPreferences.Editor edtr = sharedPref.edit();

            edtr.putString(key0, "loggedOut");
            edtr.remove(key1);
            edtr.remove(key2);

            edtr.apply();
            startActivity(new Intent(VacancyList.this, MainActivity.class));

            return true;
        }
        default:
            return super.onOptionsItemSelected(item);
    }
}

4) activity_vacancy_list.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/detail_backdrop_height"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:fitsSystemWindows="true">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp">

            <ImageView
                android:id="@+id/backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax"
                android:contentDescription="" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center|start"

                app:layout_collapseMode="parallax"
                android:orientation="horizontal">
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/sortBy"
                    android:text="@string/txtVWPrompt"
                    android:textSize="@dimen/spinner_text_size"

                    android:layout_marginLeft="40dp"
                    android:layout_marginStart="40dp"
                    android:layout_marginRight="40dp"
                    android:layout_marginEnd="40dp"/>
                <Spinner
                    android:id="@+id/spinner1"
                    android:spinnerMode="dropdown"
                    android:dropDownVerticalOffset="90dp"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:entries="@array/sorting_type"/>
            </LinearLayout>

            **<android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_collapseMode="pin" >**

                <android.support.v7.widget.SearchView
                    android:id="@+id/search"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>

            </android.support.v7.widget.Toolbar>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/refresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
            <include layout="@layout/recyclerview_content"/>
    </android.support.v4.widget.NestedScrollView>
    </android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>

5) toolbar_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/tools">
    <item android:id="@+id/aboutPage"
        android:title="@string/about_page"
        app:showAsAction="never"
        android:clickable="false"/>
    <item android:id="@+id/logOut"
        android:title="@string/logout"
        app:showAcAction="never"
        android:clickable="false"/>
</menu>

Logcat Output when pressing on the either of the items.

11-01 04:13:06.317 31673-31673/fyp.inrestaurant W/InputEventReceiver: Attempted to finish an input event but the input event receiver has already been disposed.

11-01 04:13:12.517 31673-31673/fyp.inrestaurant W/InputEventReceiver: Attempted to finish an input event but the input event receiver has already been disposed.

What I've done

I actually don't quite get what the answer was saying, as the answer only indicated what would happen to onCreateOptionsMenu and the onOptionsItemSelected() is not shown to have any changes. So, the only thing I've tried is to put android:clickable = false in the corresponding items in to the toolbar_menu.xml file.
Custom Toolbar onOptionsItemSelected not working

Edit 1 : Adapter & RestInfo

1) RestInfo.java

//For adapter, no direct relationship with restaurant info
public class RestInfo implements Parcelable {
    //Displayed in CardView (and RestaurantInfo)
    //protected ImageView imgVw;
    protected String restName;
    protected String restLot;
    protected String restLoc;
    protected int restVacant;

    //Displayed in RestaurantInfo
    protected String restType;
    protected String restNo;
    protected String restEmail;

    //DIsplayed for Admin
    protected String restOwn;
    protected int restID;

    //Status
    private boolean objIS_EMPTY = true;

    public RestInfo(int id, String name, String type, String loc,  String lot, int vacant, String own, String no, String email) {
        init(id, name, type, loc, lot, vacant, own, email, no);
    }

    public boolean getEMPTY_Status(){
        return objIS_EMPTY;
    }

    private boolean isEmpty(){
        return restName.equals("") && restLot.equals("") && restLoc.equals("") && restVacant == 0 && restType.equals("") && restNo.equals("") && restEmail.equals("") && restOwn.equals("");
    }

    private void init(int id, String name, String type, String loc,  String lot, int vacant, String own, String no, String email)
    {
        restID = id;
        restName = name;
        restLot = lot;
        restLoc = loc;
        restVacant = vacant;
        restType = type;
        restNo = no;
        restEmail = email;
        restOwn = own;

        objIS_EMPTY = isEmpty();


    }

    public String getRestName(){
        return restName;
    }

    public String getRestLot(){
        return restLot;
    }

    public String getRestLoc(){
        return restLoc;
    }

    public int getResVacant(){
        return restVacant;
    }

    public String getRestType(){
        return restType;
    }

    public String getRestNo(){
        return restNo;
    }

    public String getRestEmail(){
        return restEmail;
    }

    public String getRestOwn(){
        return restOwn;
    }

    public int getRestID(){
        return restID;
    }

    public boolean checkFields(RestInfo arg){
        return arg.getRestName().equals(this.getRestName()) && arg.getRestEmail().equals(this.getRestEmail())
                && arg.getRestLoc().equals(this.getRestLoc()) && arg.getRestLot().equals(this.getRestLot())
                && arg.getRestNo().equals(this.getRestNo()) && arg.getRestType().equals(this.getRestType())
                && arg.getRestOwn().equals(this.getRestOwn()) && arg.getResVacant() == this.getResVacant();
    }


    protected RestInfo(Parcel in) {
        //imgVw = (ImageView) in.readValue(ImageView.class.getClassLoader());
        restName = in.readString();
        restLot = in.readString();
        restLoc = in.readString();
        restVacant = in.readInt();
        restType = in.readString();
        restNo = in.readString();
        restEmail = in.readString();
        restOwn = in.readString();
        restID = in.readInt();
        objIS_EMPTY = in.readByte() != 0x00;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        //dest.writeValue(imgVw);
        dest.writeString(restName);
        dest.writeString(restLot);
        dest.writeString(restLoc);
        dest.writeInt(restVacant);
        dest.writeString(restType);
        dest.writeString(restNo);
        dest.writeString(restEmail);
        dest.writeString(restOwn);
        dest.writeInt(restID);
        dest.writeByte((byte) (objIS_EMPTY ? 0x01 : 0x00));
    }

    @SuppressWarnings("unused")
    public static final Parcelable.Creator<RestInfo> CREATOR = new Parcelable.Creator<RestInfo>() {
        @Override
        public RestInfo createFromParcel(Parcel in) {
            return new RestInfo(in);
        }

        @Override
        public RestInfo[] newArray(int size) {
            return new RestInfo[size];
        }
    };
}

2) RestInfoAdapter.java

public class RestInfoAdapter extends RecyclerView.Adapter<RestInfoAdapter.RestInfo_ViewHolder>
{

    private Context context;
    private ArrayList<RestInfo> rInf_LIST;
    //Java Array starts at 0
    int selectedItemID = -1;

    public RestInfoAdapter(Context mContext, ArrayList<RestInfo> rInf)
    {
        this.context = mContext;
        rInf_LIST = rInf;
    }

    @Override
    public RestInfo_ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View itemVw = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, parent, false);
        return new RestInfo_ViewHolder(itemVw);
    }

    @Override
    public void onBindViewHolder(final RestInfo_ViewHolder holder, int position)
    {
        RestInfo rInf = rInf_LIST.get(position);
        holder.rName.setText(rInf.getRestName());
        holder.rLot.setText(rInf.getRestLot());
        holder.rVacancy_PROGBAR.setProgress(rInf.getResVacant());
        holder.progBarVal.setText(Integer.toString(rInf.getResVacant()/10));
    }

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

    public class RestInfo_ViewHolder extends RecyclerView.ViewHolder
    {
        public TextView rName, rLot, progBarVal;
        public ProgressBar rVacancy_PROGBAR;

        public RestInfo_ViewHolder(final View itemView)
        {
            super(itemView);

            rName = (TextView)itemView.findViewById(R.id.txtVw_RestName);
            rLot = (TextView)itemView.findViewById(R.id.txtVw_RestLot);
            progBarVal = (TextView)itemView.findViewById(R.id.progBarTextValue);

            rVacancy_PROGBAR = (ProgressBar)itemView.findViewById(R.id.progBar);

            itemView.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View view) {
                    selectedItemID = getAdapterPosition();
                    Intent intent = new Intent(context, RestaurantInfo.class);

                    //Commented out
                    //Reason : Much better object passing method is used
                    //ArrayList<RestInfo> temp = new ArrayList<>();
                    //temp.add(rInf_LIST.get(selectedItemID));
                    //intent.putParcelableArrayListExtra("selected_Rest", temp);

                    intent.putExtra("selected_Rest", rInf_LIST.get(selectedItemID));
                    context.startActivity(intent);
                }
            });
        }
    }
}

Upvotes: 1

Views: 304

Answers (1)

Nicky HFE
Nicky HFE

Reputation: 143

Solved

Thanks to @DeeV, the problem lies in the part where there is a toolbar but no codes to tell the app that that toolbar is being used as actionbar.

Hence, the addition of setSupportActionBar(toolBar); will solve the problem.

Updated code for onCreate()

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

        devOnly = (FloatingActionButton)findViewById(R.id.devOnly);
        devOnly.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String prefName = getString(R.string.prefName), key0 = getString(R.string.key0), key1 = getString(R.string.key1), key2 = getString(R.string.key2);

                SharedPreferences sharedPref = getSharedPreferences(prefName, Context.MODE_PRIVATE);
                SharedPreferences.Editor edtr = sharedPref.edit();

                edtr.putString(key0, "loggedOut");
                edtr.remove(key1);
                edtr.remove(key2);

                edtr.apply();
                startActivity(new Intent(VacancyList.this, MainActivity.class));
            }
        });

        toolBar = (Toolbar)findViewById(R.id.toolbar);
        toolBar.inflateMenu(R.menu.toolbar_menu);
        setSupportActionBar(toolBar);

        rInf_LIST = new ArrayList<>();

        //AsyncTask calls
        new ListGetterTask(true).execute();

        //Setup Recycler View with the appropriate adapter and layout.
        recyclVw = (RecyclerView)findViewById(R.id.recyclerView);
        adapter = new RestInfoAdapter(this, rInf_LIST);
        GridLayoutManager glm = new GridLayoutManager(this, 1);

        recyclVw.setLayoutManager(glm);
        recyclVw.setAdapter(adapter);

        refresh = (SwipeRefreshLayout)findViewById(R.id.refresh);
        refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                new Handler().post(new Runnable() {
                    @Override
                    public void run() {
                        new ListGetterTask(false).execute();
                        Toast.makeText(VacancyList.this, "ListGetter Executed", Toast.LENGTH_SHORT).show();
                        refresh.setRefreshing(false);
                    }
                });
            }
        });
    }

Upvotes: 2

Related Questions