編輯:關於Android編程
先上效果圖吧
點擊加號
勾選需要的應用
點擊添加
這裡出現了三種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'
}
布局文件:
三種item的布局:
card_plus.xml 加號的布局
card_no_check.xml 沒有checkBox的item布局
card_check.xml 有checkBox的item布局
重點就在Adapter裡面了,RecyclerView繼承的是RecyclerView.Adapter<>
因為這裡主要是要加載三種不同的item
所以要重寫getItemViewType(int position)方法,以決定元素的布局使用哪種類型。由於有三種item,所以也要寫三個ViewHolder,繼承RecyclerView.ViewHolder.另外還要重寫的方法有onCreateViewHolder()用於渲染具體的ViewHolder,onBindViewHolder用於綁定ViewHolder的數據。
RecyclerViewAdapter.java
public class RecyclerViewAdapter extends RecyclerView.Adapterimplements View.OnClickListener { private List 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 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); } }
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);
@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 mPackageInfoList;
private ApplicationInfo mApplicationInfo;
private static List 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 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 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;
}
}
Fragment2.java
public class Fragment2 extends Fragment implements RecyclerViewAdapter.OnRecyclerViewItemClickListener {
private View mView;
private RecyclerView mRecyclerView;
private List mPackList; //全部的應用的信息列表
private List 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);
}
}
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,就只是將所有應用的圖標和名稱顯示出來。
Android中WebView的一些簡單用法
Android中WebView的一些簡單用法一直想寫一個關於 WebView 控件的 一些簡單運用,都沒什麼時間,這次也是擠出時間寫的,裡面的一些基礎知識就等有時間再更新
Android應用開發編譯框架流程與IDE及Gradle概要
1 背景建議閱讀本文之前先閱讀《Android Studio入門到精通》和《Groovy腳本基礎全攻略》及《Gradle腳本基礎全攻略》三篇博客作為背景知識,這樣才能更好
android Spinner和數值選擇器使用demo
關鍵部分代碼如下 1、Spinnner 在布局文件中: 定義對象: private
“拯救”手機的最後一絲剩余電量
當我們外出時,最尴尬的情景就是剩余電量不到10%,而且身邊還沒有移動電源和任何充電設備。此時,如果拯救剩余電量,並盡可延長手機的待機時間呢?很多Androi