編輯:關於Android編程
[java]
<SPAN style="FONT-FAMILY: SimHei; FONT-SIZE: 18px"></SPAN>
一直沒認真看過android的源碼,也不太敢看,稀裡糊塗也敲了一年的代碼,現在想好好學習了,就把常用的源碼都看了一下,小伙伴們來漲姿勢吧,有錯誤的地方,直接指出,我臉厚不怕丟人。來吧。
剛開始學android的時候我經常使用SimpleAdapter,但是後來經常用到的對象實體,SimpleAdapter也就不符合要求了,一直自己繼承BaseAdapter,但是有的地方用SimpleAdapter還是比較方便的,一句話就搞定了,也不用寫Adapter,所以來悄悄源碼吧。
SimpleAdapter的初始化:
[java]
<SPAN style="FONT-FAMILY: SimHei; FONT-SIZE: 18px"></SPAN>
[java]
<SPAN style="FONT-FAMILY: SimHei; FONT-SIZE: 18px"></SPAN><PRE class=java name="code">SimpleAdapter sAdapter=new SimpleAdapter(this, mList, R.layout.activity_main,new String[]{"name","pwd"},new int[]{R.id.tv_name,R.id.tv_pwd});</PRE>
<PRE></PRE>
<PRE class=java name="code"><SPAN style="FONT-FAMILY: SimHei; FONT-SIZE: 18px">下面是android的源碼,加了詳細的注釋,不用再多說:</SPAN></PRE><PRE class=java name="code" sizcache="1" sizset="7"><SPAN style="FONT-FAMILY: SimHei; FONT-SIZE: 18px"></SPAN><PRE class=java name="code">public class SimpleAdapter extends BaseAdapter implements Filterable {
private int[] mTo; // 指向布局裡面控件的id 比如:R.id.btn
private String[] mFrom; // 數據來源,來自Map裡面的key
private ViewBinder mViewBinder;// 接口類型,裡面有個setViewValue方法,用於出現特殊類型控件比如:drawable的時候在外部初始化接口,實現具體方法
private List<? extends Map<String, ?>> mData;// 用List打包的Map數據源
private int mResource;// 布局
private int mDropDownResource;// 不知道干嘛用的,但是估計也是留給外部調用的
private LayoutInflater mInflater;// 這個大家都知道,LayoutInflater用來載入界面
private SimpleFilter mFilter;// 過濾器,一般用不到
private ArrayList<Map<String, ?>> mUnfilteredData;
// SimpleAdapter初始化,將傳進了的參數都賦給本地的對應變量
public SimpleAdapter(Context context, List<? extends Map<String, ?>> data,
int resource, String[] from, int[] to) {
mData = data;
mResource = mDropDownResource = resource;
mFrom = from;
mTo = to;
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/*
* ListView 針對每個item,要求 adapter “返回一個視圖” (getView),
* 也就是說ListView在開始繪制的時候,系統首先調用getCount()函數,根據他的返回值得到ListView的長度,
* 然後根據這個長度,調用getView()一行一行的繪制ListView的每一項。如果你的getCount()返回值是0的話,
* 列表一行都不會顯示,如果返回1,就只顯示一行。返回幾則顯示幾行。如果我們有幾千幾萬甚至更多的item要顯示怎麼辦?
* 為每個Item創建一個新的View?不可能!!!實際上Android早已經緩存了這些視圖,大家可以看下下面這個截圖來理解下,
* 這個圖是解釋ListView工作原理的最經典的圖了大家可以收藏下,不懂的時候拿來看看,加深理解,
* 其實Android中有個叫做Recycler的構件
*/
public int getCount() {
return mData.size();
}
public Object getItem(int position) {
return mData.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// 調用createViewFromResource來優化內存
return createViewFromResource(position, convertView, parent, mResource);
}
/*
* ListView的機制在這裡再說一下,當第一個數據來getView的時候convertView肯定是null,
* 那麼就用mInflater.inflate(resource, parent,
* false)給它初始化一個View,但是當一屏滑到底了,第一個item,滑出了屏幕,那麼它將
* 從底部出來,那時候convertView就不為null,這個方法的好處就是當convertView不為null
* 的時候不用加載布局,直接使用convertView, 節省了一步,這也是所說的優化ListView的第一個步驟。
*/
private View createViewFromResource(int position, View convertView,
ViewGroup parent, int resource) {
View v;
if (convertView == null) {
v = mInflater.inflate(resource, parent, false);
} else {
v = convertView;
}
// 這個方法是核心
bindView(position, v);
return v;
}
public void setDropDownViewResource(int resource) {
this.mDropDownResource = resource;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return createViewFromResource(position, convertView, parent,
mDropDownResource);
}
// 這個方法的主要功能就是按照 to數組裡面控件的順序挨個賦值,比如new int[]{R.id.tv_name,R.id.tv_pwd}。
private void bindView(int position, View view) {
final Map dataSet = mData.get(position);// 找到對應的position位置的map數據
// 如果沒找到跳出
if (dataSet == null) {
return;
}
/*
* 將外部實現的ViewBinder,賦值給本地,SimpleAdapter能夠實現:
* checkBox,CheckedTextView,TextView
* ,ImageView,數據類型也就是Boolean,Integer,Stirng, 所以特殊數據類型的時候才用到ViewBinder
* ,如果沒用到就不需要外部實現ViewBinder接口和裡面的方法
*/
final ViewBinder binder = mViewBinder;
final String[] from = mFrom;
final int[] to = mTo;
final int count = to.length;
//view.findViewById(to[i]),循環找控件
for (int i = 0; i < count; i++) {
final View v = view.findViewById(to[i]);
//如果v不為空的話,找到對應的數據,Object類型的data轉換為String,因為boolean在map裡面純的也是true或者false
if (v != null) {
final Object data = dataSet.get(from[i]);
String text = data == null ? "" : data.toString();
if (text == null) {
text = "";
}
//標志變量bound,判斷外部有沒有實現ViewBinder,如果實現了,就執行binder.setViewValue(v, data, text),如果符合特殊條件,就返回true
boolean bound = false;
if (binder != null) {
bound = binder.setViewValue(v, data, text);
}
//如果滿足if (!bound)那麼bound就還是false,說明是普通數據
if (!bound) {
//查看v是不是Checkable的實例化類型,滿足的情況可能是CheckBox,CheckedTextView
if (v instanceof Checkable) {
//如果數據類型是boolean,那麼就是CheckBox
if (data instanceof Boolean) {
((Checkable) v).setChecked((Boolean) data);
//如果不是CheckBox,那麼判斷是不是繼承TextView的CheckedTextView,是的話賦值,不是就拋出異常
} else if (v instanceof TextView) {
setViewText((TextView) v, text);
} else {
throw new IllegalStateException(v.getClass()
.getName()
+ " should be bound to a Boolean, not a "
+ (data == null ? "<unknown type>"
: data.getClass()));
}
//如果不是Checkable的實例化類型,判斷是不是TextView的實例化類型
} else if (v instanceof TextView) {
setViewText((TextView) v, text);
//都不是以上情況,就判斷一下是不是ImageView的實例化類型
} else if (v instanceof ImageView) {
//這裡只滿足數據類型為int也就是R.drawable.ic,和String類型的url,如果想實現直接用drawbale,就要實現ViewBinder
if (data instanceof Integer) {
setViewImage((ImageView) v, (Integer) data);
} else {
setViewImage((ImageView) v, text);
}
} else {
throw new IllegalStateException(
v.getClass().getName()
+ " is not a "
+ " view that can be bounds by this SimpleAdapter");
}
}
}
}
}
public ViewBinder getViewBinder() {
return mViewBinder;
}
public void setViewBinder(ViewBinder viewBinder) {
mViewBinder = viewBinder;
}
public void setViewImage(ImageView v, int value) {
v.setImageResource(value);
}
public void setViewImage(ImageView v, String value) {
try {
v.setImageResource(Integer.parseInt(value));
} catch (NumberFormatException nfe) {
v.setImageURI(Uri.parse(value));
}
}
public void setViewText(TextView v, String text) {
v.setText(text);
}
public Filter getFilter() {
if (mFilter == null) {
mFilter = new SimpleFilter();
}
return mFilter;
}
public static interface ViewBinder {
boolean setViewValue(View view, Object data, String textRepresentation);
}
//這個不知道干嘛用的,也沒用過,好像是過濾數據的
private class SimpleFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence prefix) {
FilterResults results = new FilterResults();
if (mUnfilteredData == null) {
mUnfilteredData = new ArrayList<Map<String, ?>>(mData);
}
if (prefix == null || prefix.length() == 0) {
ArrayList<Map<String, ?>> list = mUnfilteredData;
results.values = list;
results.count = list.size();
} else {
String prefixString = prefix.toString().toLowerCase();
ArrayList<Map<String, ?>> unfilteredValues = mUnfilteredData;
int count = unfilteredValues.size();
ArrayList<Map<String, ?>> newValues = new ArrayList<Map<String, ?>>(
count);
for (int i = 0; i < count; i++) {
Map<String, ?> h = unfilteredValues.get(i);
if (h != null) {
int len = mTo.length;
for (int j = 0; j < len; j++) {
String str = (String) h.get(mFrom[j]);
String[] words = str.split(" ");
int wordCount = words.length;
for (int k = 0; k < wordCount; k++) {
String word = words[k];
if (word.toLowerCase().startsWith(prefixString)) {
newValues.add(h);
break;
}
}
}
}
}
results.values = newValues;
results.count = newValues.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
// noinspection unchecked
mData = (List<Map<String, ?>>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}</PRE><BR>
<STRONG><BR>
最近在公司漲了很多姿勢,大部分是Java的繼承,接口,多態,抽象這些學過但是理解很膚淺的東西,以前自己寫軟件沒什麼規范,也沒怎麼去抽象,所以代碼很不上檔次,老鳥看到我的代碼就笑話我,現在我准備好好學一下,希望自己有一天也能寫出很正規的代碼。</STRONG><PRE class=java name="code"></PRE><PRE class=java name="code"></PRE>
<PRE></PRE>
<PRE></PRE>
</PRE>
微信好友刪除怎麼找回?很多朋友誤刪了微信好友很後悔,但是找不到恢復的方法,又不好意思重新加回好友,以免被好友發現,下面,小編就告訴大家微信好友刪除怎麼找回的
簡單實現的短信發送器,效果截圖如下: 其中的java代碼如下:package com.mxy.smssend; import java.util.ArrayList;
目前針對公司Android端的SDK進行實際測試,反映出存在網絡加載資源緩慢的問題,在知曉目前CDN的可能存在不穩定的情況下,針對sdk本身的網絡模塊進行了相應的分析,整
在學習Android開發的過程你,你往往會去借鑒別人的應用是怎麼開發的,那些漂亮的動畫和精致的布局可能會讓你愛不釋手,作為一個開發者,你可能會很想知道這些效果界面是怎麼去