一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

創(chuàng)新源于模仿之二:美化ListView的嘗試

 orion360doc 2011-03-22

 創(chuàng)新源于模仿之二:美化ListView的嘗試 收藏 此文于2011-03-16被推薦到CSDN首頁
如何被推薦?
今天繼續(xù),模仿MIUI做那個(gè)Contacts的ListView,如下圖:

 

其實(shí)可以這樣歸納一下我們要做的事情:

1. 按首字母分組,顯示一個(gè)分組的標(biāo)簽頭。

2. 在右邊做一個(gè)全字母表,可以用手指上下滑動(dòng)快速選擇字母分組。

3. 再做一個(gè)當(dāng)前選中的那個(gè)字母的顯示。

先說第一件事。我們已經(jīng)了解ListView/ListAdapter組合做出一個(gè)列表界面。那么,怎么在列表中顯示一些不可選且模樣不同的行,在SDK提供的例子其實(shí)是有相關(guān)代碼可供參考的。

相關(guān)的代碼是在ListAdapter中這兩個(gè)方法:

+ expand sourceview plaincopy to clipboardprint?
@Override 
public boolean areAllItemsEnabled() {  
   return false; //不是所有項(xiàng)都可選  
}  
@Override 
public boolean isEnabled(int position) {  
   return !getItem(position).name.startsWith("@section"); //如果名字以@section開頭,則該項(xiàng)不可選  

@Override
public boolean areAllItemsEnabled() {
   return false; //不是所有項(xiàng)都可選
}
@Override
public boolean isEnabled(int position) {
   return !getItem(position).name.startsWith("@section"); //如果名字以@section開頭,則該項(xiàng)不可選
}

簡言之,在position這個(gè)項(xiàng)是否可選完全可以由你來控制的。

模樣的問題也容易解決,只是這樣做的效率會降低:

view plaincopy to clipboardprint?
public View getView(int position, View convertView, ViewGroup parent) {  
// 如果每一項(xiàng)都一樣,就可以這樣。  
//   if(convertView==null){  
//   convertView=mInflater.inflate(R.layout.friends_list_row, null);  
//   }  
 
//但我們每一項(xiàng)的模樣都可能不一樣,只能這樣了  
FriendInfo item = (FriendInfo)getItem(position);  
if(item!=null){  
if(!item.name.startsWith("@section")){  
convertView=mInflater.inflate(R.layout.friends_list_row, null);  
//... ...  
convertView.setTag(item);  
}  
else {  
convertView=mInflater.inflate(R.layout.friends_list_section, null);  
// ... ...  
}  
}  
return convertView;  

public View getView(int position, View convertView, ViewGroup parent) {
// 如果每一項(xiàng)都一樣,就可以這樣。
//  if(convertView==null){
//  convertView=mInflater.inflate(R.layout.friends_list_row, null);
//  }

//但我們每一項(xiàng)的模樣都可能不一樣,只能這樣了
FriendInfo item = (FriendInfo)getItem(position);
if(item!=null){
if(!item.name.startsWith("@section")){
convertView=mInflater.inflate(R.layout.friends_list_row, null);
//... ...
convertView.setTag(item);
}
else {
convertView=mInflater.inflate(R.layout.friends_list_section, null);
// ... ...
}
}
return convertView;
}
 

可以運(yùn)行看看,第一個(gè)問題解決了。

第二個(gè)問題的處理就是找一張圖,放在ListView的右邊即可。先看看我們的Layout文件片斷:

注意這個(gè)QuickAlphabeticBar是我們自定義的一個(gè)View,extends ImageButton,所以你可以先試試用ImageButton放這兒也能很快看到效果。

view plaincopy to clipboardprint?
<FrameLayout 
            android:layout_width="fill_parent"   
            android:layout_height="0.0dip"   
            android:layout_weight="1.0"> 
         
       <ListView   
android:id="@id/friends_list" 
android:scrollbars="vertical" 
android:layout_width="fill_parent"   
android:layout_height="fill_parent" 
android:layout_marginLeft="0.0dip"   
android:drawSelectorOnTop="false" 
android:scrollingCache="true"   
android:layout_weight="1.0" 
android:fastScrollEnabled="false"   
android:footerDividersEnabled="true" 
android:cacheColorHint="#00000000" 
style="@style/Widget.ListViewGreen" 
/> 
   
<cn.sharetop.xmessenger.ui.QuickAlphabeticBar 
android:layout_gravity="top|right|center"   
android:id="@id/fast_scroller"   
android:background="@null"   
android:layout_width="wrap_content"   
android:layout_height="wrap_content"   
android:layout_marginTop="10.0px"   
android:scaleType="centerInside" 
android:src="@drawable/contact_list_scroll_long" /> 
   
  <TextView 
  android:id="@id/fast_position" 
     android:textSize="48dip" 
     android:textColor="#99FFFFFF" 
     android:background="@drawable/fast_scroller_overlay" 
     android:layout_gravity="center_horizontal|top" 
     android:padding="2dip" 
     android:layout_margin="24dip" 
     android:layout_width="@dimen/header_width" 
     android:layout_height="@dimen/header_width" 
     android:gravity="center"/> 
      
</FrameLayout> 
<FrameLayout
         android:layout_width="fill_parent"
         android:layout_height="0.0dip"
         android:layout_weight="1.0">
      
       <ListView
android:id="@id/friends_list"
android:scrollbars="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="0.0dip"
android:drawSelectorOnTop="false"
android:scrollingCache="true"
android:layout_weight="1.0"
android:fastScrollEnabled="false"
android:footerDividersEnabled="true"
android:cacheColorHint="#00000000"
style="@style/Widget.ListViewGreen"
/>
 
<cn.sharetop.xmessenger.ui.QuickAlphabeticBar
android:layout_gravity="top|right|center"
android:id="@id/fast_scroller"
android:background="@null"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10.0px"
android:scaleType="centerInside"
android:src="@drawable/contact_list_scroll_long" />
 
  <TextView
  android:id="@id/fast_position"
     android:textSize="48dip"
     android:textColor="#99FFFFFF"
     android:background="@drawable/fast_scroller_overlay"
     android:layout_gravity="center_horizontal|top"
     android:padding="2dip"
     android:layout_margin="24dip"
     android:layout_width="@dimen/header_width"
     android:layout_height="@dimen/header_width"
     android:gravity="center"/>
   
</FrameLayout>

很好,這個(gè)字母表有了,因?yàn)槲覀冃枰獙κ种冈谏厦婊瑒?dòng)時(shí)的事件進(jìn)行處理,所以我們自定義它,無非就是要處理這個(gè)onTouchEvent(MotionEvent event) 事件罷了,怎么處理?大家應(yīng)該都想到了,就是根據(jù)手指所在位置算一下是哪個(gè)字母。

所以呢,我們先處理一下那個(gè)ListAdapter,讓它implements SectionIndexer。

view plaincopy to clipboardprint?
public class FriendsListAdapter extends ArrayAdapter<FriendInfo> implements SectionIndexer{  
private Context mContext;  
private LayoutInflater mInflater;  
private HashMap<String, Integer> alphaIndexer;   
private String[] sections = new String[0];   
public FriendsListAdapter(Context context, int textViewResourceId,  
List<BuddyInfo> objects) {  
super(context, textViewResourceId, objects);  
mContext=context;  
mInflater=LayoutInflater.from(mContext);  
initSections(objects);  
}  
//......  
@Override 
public int getPositionForSection(int section)   {   
          String letter = sections[section];   
          return alphaIndexer.get(letter);   
    }   
   
@Override 
public int getSectionForPosition(int position)  {   
        int prevIndex = 0;   
        for(int i = 0; i < sections.length; i++)         {   
            if(getPositionForSection(i) > position && prevIndex <= position) {   
                prevIndex = i;   
                break;   
            }   
            prevIndex = i;   
        }   
        return prevIndex;   
    }   
@Override 
public Object[] getSections() {  
return sections;   
}  
private void initSections(List<BuddyInfo> items){  
alphaIndexer = new HashMap<String, Integer>();   
        for(int i = items.size() - 1; i >= 0; i--) {   
            BuddyInfo element = items.get(i);   
            String firstChar = element.sortKey;//.substring(0, 1).toUpperCase();   
            if(firstChar.charAt(0) > 'Z' || firstChar.charAt(0) < 'A')   
                firstChar = "#";   
            alphaIndexer.put(firstChar, i);   
        }   
        Set<String> keys = alphaIndexer.keySet();   
        Iterator<String> it = keys.iterator();   
        ArrayList<String> keyList = new ArrayList<String>();   
        while(it.hasNext())   
            keyList.add(it.next());   
        Collections.sort(keyList);   
        sections = new String[keyList.size()];   
        keyList.toArray(sections);   
}  

public class FriendsListAdapter extends ArrayAdapter<FriendInfo> implements SectionIndexer{
private Context mContext;
private LayoutInflater mInflater;
private HashMap<String, Integer> alphaIndexer;
private String[] sections = new String[0];
public FriendsListAdapter(Context context, int textViewResourceId,
List<BuddyInfo> objects) {
super(context, textViewResourceId, objects);
mContext=context;
mInflater=LayoutInflater.from(mContext);
initSections(objects);
}
//......
@Override
public int getPositionForSection(int section)   {
          String letter = sections[section];
          return alphaIndexer.get(letter);
    }
 
@Override
public int getSectionForPosition(int position)  {
        int prevIndex = 0;
        for(int i = 0; i < sections.length; i++)         {
            if(getPositionForSection(i) > position && prevIndex <= position) {
                prevIndex = i;
                break;
            }
            prevIndex = i;
        }
        return prevIndex;
    }
@Override
public Object[] getSections() {
return sections;
}
private void initSections(List<BuddyInfo> items){
alphaIndexer = new HashMap<String, Integer>();
        for(int i = items.size() - 1; i >= 0; i--) {
         BuddyInfo element = items.get(i);
            String firstChar = element.sortKey;//.substring(0, 1).toUpperCase();
            if(firstChar.charAt(0) > 'Z' || firstChar.charAt(0) < 'A')
                firstChar = "#";
            alphaIndexer.put(firstChar, i);
        }
        Set<String> keys = alphaIndexer.keySet();
        Iterator<String> it = keys.iterator();
        ArrayList<String> keyList = new ArrayList<String>();
        while(it.hasNext())
            keyList.add(it.next());
        Collections.sort(keyList);
        sections = new String[keyList.size()];
        keyList.toArray(sections);
}
}

然后,在QuickAlphabeticBar里的onTouchEvent里,我們可以快速定位到相應(yīng)的段上:

view plaincopy to clipboardprint?
@Override 
public boolean onTouchEvent(MotionEvent event) {  
int act=event.getAction();  
//......  
float y = event.getY();  
//算手指位置,找到對應(yīng)的段,讓mList移動(dòng)段開頭的位置上  
if(mListAdapter!=null){  
int x=getAlphabeticPostion(y);  
if(x<0)x=0;  
if(x>=mSections.length) x=mSections.length-1;  
int pos=((SectionIndexer)mListAdapter).getPositionForSection(x);  
this.mList.setSelectionFromTop(pos, 0);  
}  
else{  
this.mList.setSelectionFromTop(getAlphabeticPostion(y),0);  
}  
return super.onTouchEvent(event);  

@Override
public boolean onTouchEvent(MotionEvent event) {
int act=event.getAction();
//......
float y = event.getY();
//算手指位置,找到對應(yīng)的段,讓mList移動(dòng)段開頭的位置上
if(mListAdapter!=null){
int x=getAlphabeticPostion(y);
if(x<0)x=0;
if(x>=mSections.length) x=mSections.length-1;
int pos=((SectionIndexer)mListAdapter).getPositionForSection(x);
this.mList.setSelectionFromTop(pos, 0);
}
else{
this.mList.setSelectionFromTop(getAlphabeticPostion(y),0);
}
return super.onTouchEvent(event);
}

OK了,現(xiàn)在我們已經(jīng)解決兩個(gè)問題了,但是如何顯示一個(gè)小的浮動(dòng)窗口提示當(dāng)前選中的段的首字母呢,也不復(fù)雜,大家注意到文章開頭那個(gè)Layout中的ID為fast_position的TextView了吧?就是它了。

view plaincopy to clipboardprint?
public class QuickAlphabeticBar extends ImageButton implements OnScrollListener {  
//... ...  
public void init(Context ctx){  
mDialogText=(TextView)((FriendsActivity)ctx).findViewById(R.id.fast_position);  
mDialogText.setVisibility(View.INVISIBLE);  
         
mReady = true;  
//... ...         
}  
//... ...  
@Override 
public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {  
if (mReady) {  
          
            if(mListAdapter!=null && mListAdapter.getCount()>0){  
             BuddyInfo item = (BuddyInfo)mListAdapter.getItem(firstVisibleItem);  
         
           char firstLetter = (item.sortKey!=null && item.sortKey.trim().length()>0)?item.sortKey.toUpperCase().charAt(0):' ';  
             
          
           if (!mShowing && firstLetter != mPrevLetter) {  
               mShowing = true;  
               mDialogText.setVisibility(View.VISIBLE);  
                
           }  
           mDialogText.setText(((Character)firstLetter).toString());  
           mHandler.removeCallbacks(mRemoveWindow);  
           mHandler.postDelayed(mRemoveWindow, 1000);  
           mPrevLetter = firstLetter;  
            }  
        }  
}  
//... ...  

public class QuickAlphabeticBar extends ImageButton implements OnScrollListener {
//... ...
public void init(Context ctx){
mDialogText=(TextView)((FriendsActivity)ctx).findViewById(R.id.fast_position);
mDialogText.setVisibility(View.INVISIBLE);
      
mReady = true;
//... ...      
}
//... ...
@Override
public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {
if (mReady) {
       
         if(mListAdapter!=null && mListAdapter.getCount()>0){
          BuddyInfo item = (BuddyInfo)mListAdapter.getItem(firstVisibleItem);
      
           char firstLetter = (item.sortKey!=null && item.sortKey.trim().length()>0)?item.sortKey.toUpperCase().charAt(0):' ';
          
       
           if (!mShowing && firstLetter != mPrevLetter) {
               mShowing = true;
               mDialogText.setVisibility(View.VISIBLE);
             
           }
           mDialogText.setText(((Character)firstLetter).toString());
           mHandler.removeCallbacks(mRemoveWindow);
           mHandler.postDelayed(mRemoveWindow, 1000);
           mPrevLetter = firstLetter;
         }
        }
}
//... ...
}
 

這段代碼就是ListView滾動(dòng)時(shí),讓mDialogText顯示出來,并且設(shè)置它的內(nèi)容為首字母即可。關(guān)鍵是那個(gè)mHandler,即1秒后要記得讓它隱藏起來。

就是這么多事情了,大家可以試試。

 

本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/sharetop/archive/2011/03/13/6246629.aspx

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲av秘片一区二区三区| 日韩不卡一区二区在线| 国产精品免费不卡视频| 婷婷一区二区三区四区| 中文字幕五月婷婷免费| 久久黄片免费播放大全| 五月婷婷亚洲综合一区| 亚洲国产中文字幕在线观看| 欧美尤物在线视频91| 日本欧美一区二区三区高清| 国产精品日韩精品一区| 午夜精品一区二区av| 男人大臿蕉香蕉大视频| 不卡在线播放一区二区三区| 欧美亚洲三级视频在线观看| 亚洲国产成人久久一区二区三区 | 视频在线播放你懂的一区| 激情爱爱一区二区三区| 操白丝女孩在线观看免费高清| 国产午夜福利在线观看精品| 国产日韩中文视频一区| 在线观看免费无遮挡大尺度视频| 精品久久久一区二区三| 经典欧美熟女激情综合网| 亚洲国产精品久久综合网| 青青操视频在线观看国产| 69久久精品亚洲一区二区| 熟妇久久人妻中文字幕| 亚洲精品中文字幕欧美| 日本亚洲精品在线观看| 欧美日韩免费观看视频| 午夜精品一区二区三区国产 | 亚洲一区二区欧美激情| 午夜福利直播在线视频| 国产又粗又爽又猛又黄的| 91欧美亚洲视频在线| 亚洲a码一区二区三区| 中文字幕av诱惑一区二区| 国产又猛又大又长又粗| 成人你懂的在线免费视频| 国产亚洲不卡一区二区|