RecyclerView加载不同item并实现其item点击事件,实现添加常用应用的功能
来源:互联网 发布:osx数据恢复 编辑:程序博客网 时间:2024/06/15 17:20
先上效果图吧
点击加号
勾选需要的应用点击添加
这里出现了三种item的样式,一种是加号,一种是应用图标加文字,最后一种是应用图标加文字还有个checkBox
这里RecyclerView是配合CardView使用的。
在AS中使用RecyclerView需要先在build.gradle中添加依赖
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.4.0' compile 'com.android.support:recyclerview-v7:23.4.0' compile 'com.android.support:cardview-v7:23.4.0'}
布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/tv_sys" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/five" android:text="@string/systems_apps" /> <android.support.v7.widget.RecyclerView android:id="@+id/recycleView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/tv_sys" /></RelativeLayout>
三种item的布局:
card_plus.xml 加号的布局
<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/two" android:layout_marginLeft="@dimen/five" android:layout_marginRight="@dimen/five" android:layout_marginTop="@dimen/two"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/img_plus_card" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@mipmap/jia_128" /> </RelativeLayout></android.support.v7.widget.CardView>
card_no_check.xml 没有checkBox的item布局
<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="@dimen/hundred_ten" android:layout_marginBottom="@dimen/two" android:layout_marginLeft="@dimen/five" android:layout_marginRight="@dimen/five" android:layout_marginTop="@dimen/two"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true"> <ImageView android:id="@+id/img_card" android:layout_width="@dimen/fifty" android:layout_height="@dimen/fifty" android:layout_centerHorizontal="true" android:layout_marginTop="@dimen/five" android:src="@mipmap/ic_launcher" /> <TextView android:id="@+id/tv_card" android:layout_width="wrap_content" android:layout_height="@dimen/sixty" android:layout_below="@id/img_card" android:layout_centerHorizontal="true" android:ellipsize="end" android:gravity="center" android:maxLength="25" android:text="icon1" android:textColor="@android:color/black" android:textSize="@dimen/font_s" /> </RelativeLayout></android.support.v7.widget.CardView>
<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="@dimen/hundred_ten" android:layout_marginBottom="@dimen/two" android:layout_marginLeft="@dimen/five" android:layout_marginRight="@dimen/five" android:layout_marginTop="@dimen/two"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true"> <ImageView android:id="@+id/img_card2" android:layout_width="@dimen/fifty" android:layout_height="@dimen/fifty" android:layout_centerHorizontal="true" android:layout_marginTop="@dimen/five" android:src="@mipmap/ic_launcher" /> <CheckBox android:id="@+id/checkbox_card2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/ten" android:layout_marginTop="@dimen/five" android:background="@drawable/checkbox_style" android:button="@null" /> <TextView android:id="@+id/tv_card2" android:layout_width="wrap_content" android:layout_height="@dimen/sixty" android:layout_below="@id/img_card2" android:layout_centerHorizontal="true" android:ellipsize="end" android:gravity="center" android:maxLength="25" android:text="icon1" android:textColor="@android:color/black" android:textSize="@dimen/font_s" /> </RelativeLayout></android.support.v7.widget.CardView>
重点就在Adapter里面了,RecyclerView继承的是RecyclerView.Adapter<>
因为这里主要是要加载三种不同的item
所以要重写getItemViewType(int position)方法,以决定元素的布局使用哪种类型。由于有三种item,所以也要写三个ViewHolder,继承RecyclerView.ViewHolder.另外还要重写的方法有onCreateViewHolder()用于渲染具体的ViewHolder,onBindViewHolder用于绑定ViewHolder的数据。
RecyclerViewAdapter.java
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements View.OnClickListener { private List<PackageMessage> mList; private PackagePreference mPreference; private OnRecyclerViewItemClickListener mListener; private static int mFlag; public final static int NO_CHECK = 0; public final static int CHECK = 1; public final static int PLUS = 2; public RecyclerViewAdapter(List<PackageMessage> list, int flag) { this.mList = list; this.mFlag = flag; mPreference = PackagePreference.getInstance(MyApplication.getContext()); } /** * 渲染具体的ViewHolder * * @param parent ViewHolder的容器 * @param viewType 根据该标志实现渲染不同类型的ViewHolder * @return */ @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //加载数据item的布局,生成VH返回 if (viewType == NO_CHECK) { return new NoCheckViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.card_no_check, parent, false)); } else if (viewType == CHECK) { return new CheckViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.card_check, parent, false)); } else if (viewType == PLUS) { return new PlusViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.card_plus, parent, false)); } else { return null; } } /** * 绑定ViewHolder的数据 * * @param holder * @param position */ @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { PackageMessage message = mList.get(position); //数据绑定 if (holder instanceof NoCheckViewHolder) { bindNoCheckViewHolder(message, (NoCheckViewHolder) holder); } else if (holder instanceof CheckViewHolder) { bindCheckViewHolder(message, (CheckViewHolder) holder); } holder.itemView.setTag(position); holder.itemView.setOnClickListener(this); } @Override public int getItemCount() { if (null == mList) { return 0; } return mList.size(); } /** * 决定元素的布局使用哪种类型 * * @param position * @return 传递给onCreateViewHolder的第二个参数 */ @Override public int getItemViewType(int position) { if (mFlag == NO_CHECK) { if (position == mList.size() - 1) { return PLUS; } return NO_CHECK; } else if (mFlag == CHECK) { return CHECK; } else { return 100; } } private void bindNoCheckViewHolder(PackageMessage message, NoCheckViewHolder holder) { holder.tv.setText(message.getLabel()); holder.img.setImageDrawable(message.getIcon()); } private void bindCheckViewHolder(PackageMessage message, final CheckViewHolder holder) { holder.tv2.setText(message.getLabel()); holder.img2.setImageDrawable(message.getIcon()); final String packageName = message.getPackageName(); holder.checkBox2.setChecked(mPreference.getPackageMessage(packageName)); holder.checkBox2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (holder.checkBox2.isChecked()) { mPreference.putPackageMessage(packageName, true); } else { mPreference.putPackageMessage(packageName, false); } } }); } public static class NoCheckViewHolder extends RecyclerView.ViewHolder { public ImageView img; public TextView tv; public NoCheckViewHolder(View itemView) { super(itemView); img = (ImageView) itemView.findViewById(R.id.img_card); tv = (TextView) itemView.findViewById(R.id.tv_card); } } public static class CheckViewHolder extends RecyclerView.ViewHolder { public CheckBox checkBox2; public ImageView img2; public TextView tv2; public CheckViewHolder(View itemView) { super(itemView); checkBox2 = (CheckBox) itemView.findViewById(R.id.checkbox_card2); img2 = (ImageView) itemView.findViewById(R.id.img_card2); tv2 = (TextView) itemView.findViewById(R.id.tv_card2); } } public static class PlusViewHolder extends RecyclerView.ViewHolder { public ImageView img_plus_card; public PlusViewHolder(View itemView) { super(itemView); img_plus_card = (ImageView) itemView.findViewById(R.id.img_plus_card); } } @Override public void onClick(View v) { if (null != mListener) { mListener.onItemClick(v, (Integer) v.getTag()); } } public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) { this.mListener = listener; } public interface OnRecyclerViewItemClickListener { void onItemClick(View view, int position); }}
由于RecyclerView没有item的点击事件,所以此处在Adapter里面添加item的点击事件,定义一个接口OnRecyclerViewItemClickListener,写一个抽象方法onItemClick(View view,int position)把当前item的position设置进去,在onBindView里面监听item的点击事件。
Activity或Fragment调用处:
我这里是使用的网格布局,所以实例化网格布局管理器GridLayoutManager,如果是线性布局,则实例化LinearLayoutManager
在实例化RecyclerViewAdapter的时候,将item的类型传过去
//线性布局管理器// LinearLayoutManager llManager = new LinearLayoutManager(mContext); GridLayoutManager glManager = new GridLayoutManager(mContext, 4); //设置布局管理器 mRecyclerView.setLayoutManager(glManager); mRecyclerView.setHasFixedSize(true); //每个选项高度固定 mRecyclerView.setItemAnimator(new DefaultItemAnimator()); mAdapter = new RecyclerViewAdapter(mCheckedList, RecyclerViewAdapter.NO_CHECK); mAdapter.setOnItemClickListener(this); mRecyclerView.setAdapter(mAdapter);
实现RecyclerViewAdapter.OnRecyclerViewItemClickListener,点击最后一个item(加号)的时候跳转到另一个Activity
@Override public void onItemClick(View view, int position) { if (position == (mCheckedList.size() - 1)) { startActivityForResult(new Intent(getActivity(), ListActivity2.class), 1); } }到这里用RecyclerView显示不同的item还有点击事件也就完成了。
下面说下这个demo的数据存储等
先获取系统安装了的应用信息
在Application里
MyApplication.java
public class MyApplication extends Application { private static Context mContext; private PackageManager mPackageManager; private List<PackageInfo> mPackageInfoList; private ApplicationInfo mApplicationInfo; private static List<PackageMessage> mPackList; @Override public void onCreate() { super.onCreate(); mContext = getApplicationContext(); mPackageManager = getPackageManager(); mPackageInfoList = mPackageManager.getInstalledPackages(0); getPackageMessage(); } public static Context getContext() { return mContext; } /** * 得到应用的包名并存储 */ private void getPackageMessage() { List<PackageInfo> systemApps = new ArrayList<>(); for (PackageInfo apps : mPackageInfoList) { if ((apps.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0) { //获取系统应用 systemApps.add(apps); } } int size = systemApps.size(); mPackList = new ArrayList<>(); PackageMessage message; for (int i = 0; i < size; i++) { message = new PackageMessage(); PackageInfo packageInfo = systemApps.get(i); mApplicationInfo = packageInfo.applicationInfo; String packageName = mApplicationInfo.packageName; Drawable drawable = mPackageManager.getApplicationIcon(mApplicationInfo); String label = (String) mPackageManager.getApplicationLabel(mApplicationInfo); message.setIcon(drawable); message.setLabel(label); message.setPackageName(packageName); mPackList.add(message); } } public static List<PackageMessage> getmPackList() { return mPackList; }}PackageMessage是一个存放应用信息的实体类
public class PackageMessage { private String packageName; //包名 private Drawable icon; //图标 private String label; //名称 private boolean isChecked; //是否选中 public String getPackageName() { return packageName; } public void setPackageName(String packageName) { this.packageName = packageName; } public Drawable getIcon() { return icon; } public void setIcon(Drawable icon) { this.icon = icon; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public boolean isChecked() { return isChecked; } public void setIsChecked(boolean isChecked) { this.isChecked = isChecked; }}
最先出现的RecyclerVIew的Fragment
Fragment2.java
public class Fragment2 extends Fragment implements RecyclerViewAdapter.OnRecyclerViewItemClickListener { private View mView; private RecyclerView mRecyclerView; private List<PackageMessage> mPackList; //全部的应用的信息列表 private List<PackageMessage> mCheckedList; //已经被选中的应用列表 private RecyclerViewAdapter mAdapter; private Context mContext; private PackagePreference mPreference; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mView = inflater.inflate(R.layout.fragment2, container, false); mRecyclerView = (RecyclerView) mView.findViewById(R.id.recycleView); return mView; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); //线性布局管理器// LinearLayoutManager llManager = new LinearLayoutManager(mContext); GridLayoutManager glManager = new GridLayoutManager(mContext, 4); //设置布局管理器 mRecyclerView.setLayoutManager(glManager); mRecyclerView.setHasFixedSize(true); //每个选项高度固定 mRecyclerView.setItemAnimator(new DefaultItemAnimator()); mContext = MyApplication.getContext(); mPreference = PackagePreference.getInstance(mContext); mPackList = MyApplication.getmPackList(); showCheckedList(); } @Override public void onItemClick(View view, int position) { if (position == (mCheckedList.size() - 1)) { startActivityForResult(new Intent(getActivity(), ListActivity2.class), 1); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1 && resultCode == 2) { showCheckedList(); } } private void showCheckedList() { mCheckedList = new ArrayList<>(); String[] names = mPreference.getAllCheckedPackageNames(); for (int i = 0; i < names.length; i++) { for (int j = 0; j < mPackList.size(); j++) { if (names[i].equals(mPackList.get(j).getPackageName())) { mCheckedList.add(mPackList.get(j)); break; } } } PackageMessage m = new PackageMessage(); mCheckedList.add(m); mAdapter = new RecyclerViewAdapter(mCheckedList, RecyclerViewAdapter.NO_CHECK); mAdapter.setOnItemClickListener(this); mRecyclerView.setAdapter(mAdapter); }}
这里采用SharedPreference来存储系统中安装的应用包名,key为包名,value为是否选中。另定义了一个字符串来存储已经选中的应用的包名。
PackagePreference.java
public class PackagePreference { private String PREFS_CHECKED_NAME = "CheckedPackageName"; private Context mContext; private static PackagePreference mPackagePreference; private SharedPreferences mSp; private SharedPreferences.Editor mEditor; private String TAG = "PackagePreference"; private StringBuilder mCheckedPackageName; private PackagePreference(Context context) { this.mContext = context; mSp = context.getSharedPreferences("checkedPackage", Context.MODE_PRIVATE); mEditor = mSp.edit(); } public static PackagePreference getInstance(Context context) { if (mPackagePreference == null) { mPackagePreference = new PackagePreference(context); } return mPackagePreference; } /** * 将应用的包名和是否被选中放进去 */ public void putPackageMessage(String packageName, boolean isChecked) { mEditor.putBoolean(packageName, isChecked).commit(); String name = getCheckedPackageName(); mCheckedPackageName = new StringBuilder(name); if (isChecked) { mCheckedPackageName.append(packageName).append(","); } else { int index = mCheckedPackageName.indexOf(packageName); mCheckedPackageName.delete(index, index + packageName.length() + 1); } putCheckedPackageName(); } public void putCheckedPackageName() { mEditor.putString(PREFS_CHECKED_NAME, mCheckedPackageName.toString()).commit(); } public String getCheckedPackageName() { return mSp.getString(PREFS_CHECKED_NAME, ""); } /** * 通过包名得知是否被选中 * * @param packageName */ public boolean getPackageMessage(String packageName) { return mSp.getBoolean(packageName, false); } /** * 得到所有选中的应用名数组 * * @return */ public String[] getAllCheckedPackageNames() { String name = getCheckedPackageName(); String[] names = name.split(","); return names; }}至于ListActivity2,就只是将所有应用的图标和名称显示出来。
1 0
- RecyclerView加载不同item并实现其item点击事件,实现添加常用应用的功能
- RecyclerView 添加头部和尾部,并实现Item的点击事件
- RecyclerView 添加头部和尾部,并实现Item的点击事件
- RecyclerView的Item点击事件实现总结
- RecyclerView实现上拉刷新,下拉加载,item点击事件
- 为RecyclerView添加item的点击事件
- 为RecyclerView添加item的点击事件
- 为RecyclerView添加item的点击事件
- 为RecyclerView添加item的点击事件
- 为RecyclerView添加item的点击事件
- 为RecyclerView添加item的点击事件
- 为RecyclerView添加item的点击事件
- 给RecyclerView的Item添加点击事件
- RecyclerView添加Item的点击事件
- 为RecyclerView添加item的点击事件
- 对RecyclerView的item添加点击事件
- 为RecyclerView添加item的点击事件
- 为RecyclerView添加item的点击事件
- noip普及组2007 奖学金
- uc-osII实时操作
- 圣经是上帝所默示和启示的
- Zookeeper 运维
- |Vijos|动态规划|P1025 小飞侠的游园方案
- RecyclerView加载不同item并实现其item点击事件,实现添加常用应用的功能
- 使用virtualenv创建独立的Python环境
- 几种关于ASM & AAM 模型代码实现的对比
- 阿里云ECS建站
- dubbo异常记录
- Maven打包可执行文件
- MFC中CPropertySheet与CTabCtrl的使用
- S.O.L.I.D:面向对象设计的5 大原则
- Java集合中的Empty与null