編輯:關於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 ListPackageMessage是一個存放應用信息的實體類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; } }
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 ListmPackList; //全部的應用的信息列表 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的一些簡單用法一直想寫一個關於 WebView 控件的 一些簡單運用,都沒什麼時間,這次也是擠出時間寫的,裡面的一些基礎知識就等有時間再更新
1 背景建議閱讀本文之前先閱讀《Android Studio入門到精通》和《Groovy腳本基礎全攻略》及《Gradle腳本基礎全攻略》三篇博客作為背景知識,這樣才能更好
關鍵部分代碼如下 1、Spinnner 在布局文件中: 定義對象: private
當我們外出時,最尴尬的情景就是剩余電量不到10%,而且身邊還沒有移動電源和任何充電設備。此時,如果拯救剩余電量,並盡可延長手機的待機時間呢?很多Androi