Toolbar of Android Support Library
In Android 3.0, ActionBar is used as the default App Bar by default for all themes, but it is rigid and difficult to design the desired style. In the v7 compatible library, Toolbar appears, it improves this problem. With the Toolbar replacing the traditional ActionBar, we need to discuss how to implement the functions on the ActionBar on the ToolBar. How to add Toolbar1, we use the v7 compatible library, so the Activity must inherit from AppCompatActivity
MainActivity extends AppCompatActivity
2. Modify the topic and remove the default ActionBar. The v7 compatibility Library provides us with a default topic without ActionBar.
Here, I set the application as a topic without an ActionBar, so that all the activities will apply this topic, but in reality not all the activities need to design their own ActionBar, therefore, we 'd better apply this topic to a separate Activity.
For example
3. Add a Toolbar to the layout
We can see that the height of the ToolBar uses the height of the system's ActionBar. In Material Design, we need to Design a throwing shadow for a view. android: elevation is usually 4dp, to be consistent with the Material Design rules, we also need to Design the coloring for the ToolBar, which is the colorPrimary color.
4. In the Code, set the Toolbar to the App Bar and set its Navigation Icon, Logo, Title, and SubTitle.
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.setNavigationIcon(R.mipmap.ic_action_back); toolbar.setLogo(R.mipmap.ic_launcher); toolbar.setTitle("Toolbar"); toolbar.setSubtitle("Toolbar SubTitle"); setSupportActionBar(toolbar);
View the effect
However, the title color is different from the overflow color, and the title color may be white.
Let's look at the effect.
Okay ~
How to Use Toolbar once we set ToolBar as the App Bar, we can use the ActionBar class method in the v7 compatibility package, for example
private void setupActionbar() { android.support.v7.app.ActionBar actionBar = getSupportActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.hide(); }
When we operate the ActionBar, it is equivalent to operating the Toolbar. Therefore, we set the title on the Acionbar, the Logo will overwrite the options menu (> = 3.0) in the action menu displayed on the toolbar. In the preceding figure, the action menu appears on the Toolbar, this operation is the same as adding the action menu to the action bar.
Define menu
Show menu
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_menu, menu); return true; }
Respond to menu events
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.favorite: Toast.makeText(this, "Favorite", Toast.LENGTH_SHORT).show(); return true; } return super.onOptionsItemSelected(item); }
Add the contextual menu contextual action mod (> = 3.0) in the action menu in the Toolbar to see the effect.
Traditionally, ListView is used, but in order to keep up with the times, I think it is time to use RecyclerView, but it does not provide the same method as ListView.
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);listView.setMultiChoiceModeListener();
Suddenly we found that RecyclerView does not have this method and can only be done by ourselves, so we need to think about how to design this problem. First, you can provide an interface in ViewHolder for the Long-press event and then implement it in Activity. When you enable contextual action mode by implementing long-press, we need to change the item color in the adapter, we can use policyitemchanged (position) to allow RecyclerView to re-call the onBindViewHolder () method to set the background color for the item. Then, we can select other items and change the color at the same time, then, return to the delete RESPONSE event of the contextual action mode to delete the item. It seems that everything is perfect, so let's implement it step by step. 1. Implement RecyclerView first
Item Layout
Implement Recycler. Adapter
public class MyAdapter extends RecyclerView.Adapter
{ private recyclerViewListener mListener; private List
mDatas; public MyAdapter(List
list, MyAdapter.recyclerViewListener listener) { mDatas = list; mListener = listener; } @Override public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); ViewHolder viewHolder = new ViewHolder(v); return viewHolder; } @Override public void onBindViewHolder(MyAdapter.ViewHolder holder, int position) { holder.title.setText(mDatas.get(position)); } @Override public int getItemCount() { return mDatas.size(); } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { TextView title; CardView cardView; public ViewHolder(View itemView) { super(itemView); title = (TextView) itemView.findViewById(R.id.maintitle); cardView = (CardView) itemView.findViewById(R.id.item_cardview); itemView.setOnClickListener(this); itemView.setOnLongClickListener(this); } @Override public void onClick(View v) { if (mListener != null) { mListener.onClick(getLayoutPosition()); } } @Override public boolean onLongClick(View v) { if (mListener != null) { return mListener.onLongClick(getLayoutPosition()); } return false; } } public interface recyclerViewListener { void onClick(int position); boolean onLongClick(int position); }}
Add the Adapter to MainActivity. java and add the empty onClick () and onLongClick () implementations.
private void setupRecyclerView() { mDatas = new ArrayList<>(); for (int i = 0; i < 100; i++) { mDatas.add(String.valueOf(i)); } mRecyclerView = (RecyclerView) findViewById(R.id.my_recyclerView); mAdapter = new MyAdapter(mDatas, this); mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); mRecyclerView.setAdapter(mAdapter); }
In this way, the RecyclerView is displayed.
2. Achieve long and short press
mCallback = new ActionMode.Callback() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { getMenuInflater().inflate(R.menu.action_mode_menu, menu); return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.delete: mActionMode.finish(); return true; } return false; } @Override public void onDestroyActionMode(ActionMode mode) { mActionMode = null; } };
@Override public void onClick(int position) { toggleSelection(position); } @Override public boolean onLongClick(int position) { if (mActionMode == null) { mActionMode = startSupportActionMode(mCallback); } toggleSelection(position); return true; } private void toggleSelection(int position) { mAdapter.toggleSelection(position); int count = mAdapter.getSelectedItemCount(); if (count == 0) { mActionMode.finish(); } else { mActionMode.setTitle(String.valueOf(count)); } }
3. Add the color to the Adapter
mSelectedItems = new SparseBooleanArray(); public void toggleSelection(int position) { if (mSelectedItems.get(position, false)) { mSelectedItems.delete(position); } else { mSelectedItems.put(position, true); } notifyItemChanged(position); }
Call policyitemchanged () to make RecyclerView call onBindViewHolder () again, and then change the background color.
@Override public void onBindViewHolder(MyAdapter.ViewHolder holder, int position) { holder.title.setText(mDatas.get(position)); holder.cardView.setBackgroundColor(mSelectedItems.get(position, false) ? Color.parseColor("#883a44b7") : Color.parseColor("#ffffffff")); }
At this time, you can see the effect
Now there are two problems: There are two "actionbar", and the background color of the action bar we want to operate is different from the theme we designed. In addition, when we click the delete menu, the selected item color is not revoked? How to solve two "actionbar" Problems
WindowActionModeOverlay indicates that the action mode overwrites the actionbar, And the actionModeBackground is the background of the action mode. Don't ask me why, because I just try it out.
After the action mode disappears, the selected item background color is not revoked? We can think about it. After the ActionModeCallback disappears, we should call onBindViewHolder () to refresh the item through yyitemchanged () again for recyclerview.
@Override public void onDestroyActionMode(ActionMode mode) { mAdapter.clearSelectedItems(); mActionMode = null; }
public void clearSelectedItems() { for (int i = 0; i < mSelectedItems.size(); i++) { notifyItemChanged(mSelectedItems.keyAt(i)); } mSelectedItems.clear(); }
OnBindViewHolder () can be refreshed again.
@Override public void onBindViewHolder(MyAdapter.ViewHolder holder, int position) { holder.title.setText(mDatas.get(position)); holder.cardView.setBackgroundColor(mSelectedItems.get(position, false) ? Color.parseColor("#883a44b7") : Color.parseColor("#ffffffff")); }
View the effect
Is it perfect ~
4. In the last step, we need to delete the selected item. This operation is of course in ActionMode. Callback.
@Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.delete: mAdapter.removeSelectedItems(); mActionMode.finish(); return true; } return false; }
For general purposes, we can
mSelectedItems = new SparseBooleanArray();
The key value in mSelectedItems, that is, the postion of item, is deleted one by one, but it is not as good as we do. This is an update process involving recyclerview, when one of the items is deleted, it will rearrange the items. In this case, the positon of the first item changes. That is to say, if the key values are [, 3] in sequence, in practice, the positon we want to delete is [1, 3, 2]. At that time, I was a bit B, and then google found the answer in this project, we can sort the key value from large to small. In this way, [1 ,. 4, 3] is changed to [4, 3, 1], so when we delete 5th, the previous order remains unchanged, so it does not affect ~
public void removeItem(int position) { mDatas.remove(position); notifyItemRemoved(position); } public void removeSelectedItems() { List
positions = new ArrayList<>(); for (int i = 0; i < mSelectedItems.size(); i++) { positions.add(mSelectedItems.keyAt(i)); } Collections.sort(positions, new Comparator
() { @Override public int compare(Integer lhs, Integer rhs) { return rhs - lhs; } }); for (int i = 0; i < positions.size(); i++) { removeItem(positions.get(i)); } }
From this article we can see the flexibility of RecyclerView and Toolbar, but here we will only talk about one corner. I will continue to improve it in the future and discuss the new controls of the Android support Library ~