学习Android从0开始之ActionBar(活动条)之提高篇
今天为大家带来actionbar的提高篇,有些时候一个列表,比如下载列表,歌曲或视频列表,这时候你想多选,这个时候可以使用actionBar来进行操作。有如下方式来进行操作: 使用上下文动作 和 ActionMode;
1、使用上下文来创建动作:
使用PopuMenu作为一个菜单资源并将其作为小型的弹出窗口轻松附加到任何试图;首先在res/menu文件夹下创建一个XML菜单文件,如下:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_delete"
android:icon="@android:drawable/ic_menu_delete"
android:title="删除" />
<item
android:id="@+id/menu_edit"
android:icon="@android:drawable/ic_menu_edit"
android:title="编辑" />
<item
android:id="@+id/menu_add"
android:icon="@android:drawable/ic_menu_add"
android:title="编辑" />
</menu>
2、为了将popumenu能够被点击了出现在每一个列表项上面,为了封装这个逻辑,现在就是自定义listview的列表项,如下:
package com.world.hello.actionbarmode;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;
/**
* 自定义listview的列表项
* Created by chengguo on 2016/4/21.
*/
public class PopupMenuListItem extends LinearLayout implements View.OnClickListener, PopupMenu.OnMenuItemClickListener {
/*自定义popupMenu*/
private PopupMenu mPopupMenu;
/*自定义文本*/
private TextView mTextView;
public PopupMenuListItem(Context context) {
super(context);
}
public PopupMenuListItem(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PopupMenuListItem(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 当自定义列表项加载到XML中加载完后调用这个方法
*/
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mTextView = (TextView) findViewById(R.id.text);
//附加单击处理程序
View contextButton = findViewById(R.id.context);
contextButton.setOnClickListener(this);
//创建上下文菜单
mPopupMenu = new PopupMenu(getContext(), contextButton);
mPopupMenu.setOnMenuItemClickListener(this);
mPopupMenu.inflate(R.menu.popupmenu);
}
/**
* 当按钮被点击后,显示popupMenu
*
* @param v
*/
@Override
public void onClick(View v) {
mPopupMenu.show();
}
/**
* popupMenu的菜单项被点击
*
* @param item
* @return
*/
@Override
public boolean onMenuItemClick(MenuItem item) {
String itemStr = mTextView.getText().toString();
switch (item.getItemId()) {
case R.id.menu_delete:
Toast.makeText(getContext(), "删除" + itemStr, Toast.LENGTH_LONG).show();
break;
case R.id.menu_edit:
Toast.makeText(getContext(), "编辑" + itemStr, Toast.LENGTH_LONG).show();
break;
case R.id.menu_add:
Toast.makeText(getContext(), "添加" + itemStr, Toast.LENGTH_LONG).show();
break;
}
return true;
}
}
XML文件如下:
<?xml version="1.0" encoding="utf-8"?>
<com.world.hello.actionbarmode.PopupMenuListItem xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<TextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:gravity="center_vertical"
android:textSize="18sp" />
<ImageView
android:id="@+id/context"
style="@style/Widget.AppCompat.Light.ActionButton.Overflow"
android:layout_width="?android:attr/listPreferredItemHeightSmall"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="false" />
</com.world.hello.actionbarmode.PopupMenuListItem>
PopuoMenuListItem是包含上下文菜单的文本项和图片按钮的LinearLayout。为一致性,我们对按钮应用
style="@style/Widget.AppCompat.Light.ActionButton.Overflow"
样式,使其外观和行为类似于溢出菜单按钮。并且创建视图时,构建了一个PopupMenu来显示R.menu.popupmen,并关联改菜单到context这个imageview上面,使点击该按钮时可以在按钮的位置弹出popupmenu。
注意ListVIew内的可点击项需要将android:focusable设置为false,否则就不能够同时单击顶层列表项
3、activity的代码如下:
package com.world.hello.actionbarmode;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity implements AbsListView.MultiChoiceModeListener {
private String[] mItems = {"item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8", "item9", "item1="};
private ListView mList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mList = new ListView(this);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.text, mItems);
mList.setAdapter(arrayAdapter);
mList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mList.setMultiChoiceModeListener(this);
setContentView(mList, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
}
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
//当每个item的点击状态改变是调用
Log.e("tag", "--- onItemCheckedStateChanged ---position = " + position + " id = " + id + " checked = " + checked);
//获取选中的列表项的个数
int count = mList.getCheckedItemCount();
//在actionbar的顶部显示选择项的个数
mode.setTitle(String.format("%d 项被选择", count));
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
//actionMode创建时被调用
Log.e("tag", "--- onCreateActionMode ---");
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.popupmenu, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
//如果ActionMode一直是无效的,可以在这里做一些其它工作来更新菜单
Log.e("tag", "--- onPrepareActionMode ---");
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
//通过条目id得到用户选择的动作
Log.e("tag", "--- onActionItemClicked ---");
switch (item.getItemId()) {
case R.id.menu_delete:
break;
case R.id.menu_edit:
break;
case R.id.menu_add:
break;
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
//退出ActionMode时调用这个方法
Log.e("tag", "--- onDestroyActionMode ---");
}
}
使用ListView来激活一个多选项的ActionMode,将要将choicMode的属性设为CHOICE_MODE_MULTIPLE_MODAL,它和传统的CHOICE_MODE_MULTIPLE不同,后者是在每个列表项上都提供一个可选则的小部件,在ActionMode处于激活状态时,它的模式表示只应用这个选择模式;
当用户选中每个条目后,我们会在onItemCheckedStateChanged()方法中得到通知,这里我们会 更新ActionMode的标题来显示当前选中条目的个数。
当用户结束选择并单击一个菜单选项时会调用onActionItemClicked()方法,因为会同时选择多个条目,所以通过getCheckedItemPositions()得到所有选择的条目,这样就可以对所有选择的条目进行操作。
下面是gif动态图:
单击右边多功能图片会在相应的位置弹出popupMenu进行单个列表项操作。
长按列表项可以激活listview的多选模式,并且多选模式下,可以选中多个,然后点击actionbar顶部的删除、编辑、添加按钮进行多选统一操作;点击actionBar左边的返回按钮就能够取消多选操作:
点击打开链接下载示例