Android UI開發(fā): 橫向ListView(HorizontalListView)及一個簡單相冊的完整實現(xiàn) (附源碼下載)
本文內容:
1、橫向ListView的所有實現(xiàn)思路;
2、其中一個最通用的思路HorizontalListView,并基于橫向ListView開發(fā)一個簡單的相冊;
3、實現(xiàn)的橫向ListView在點擊、瀏覽時item背景會變色,并解決了listview里setSelected造成item的選擇狀態(tài)混亂的問題。
眾所周知,ListView默認的方向是垂直的,但有些時候人們更喜歡橫向ListView??v觀整個網絡,橫向ListView的實現(xiàn)思路如下:
1、在布局里用HorizontalScrollView包含一個ListView,參考這里;
2、利用GridView,把它的行數(shù)設為1行;
3、有人繼承ListView構造了一個HorizontalScrollListView,參見:這里
4、國外一位大牛繼承AdapterView
下面看源碼:
這是Activity的布局文件:activity_main.xml
[html]
view plaincopyprint???
這是橫向listview的每個item的布局,圖片+文字,horizontal_list_item.xml
[html]
view plaincopyprint???
下面文件是selector_imageview_background.xml,這是大圖片你點擊瀏覽時背景發(fā)生變化的selector,沒有啥實際作用。
[html]
view plaincopyprint???
下面是每個item的selector,在focus和select時顏色會發(fā)生變化:selector_item_background.xml
[html]
view plaincopyprint???
主程序:MainActivity.java
[java]
view plaincopyprint?package?org.yanzi.testhorizontallistview;????import?org.yanzi.ui.HorizontalListView;??import?org.yanzi.ui.HorizontalListViewAdapter;????import?android.app.Activity;??import?android.os.Bundle;??import?android.view.Menu;??import?android.view.View;??import?android.widget.AdapterView;??import?android.widget.AdapterView.OnItemClickListener;??import?android.widget.ImageView;????public?class?MainActivity?extends?Activity?{??????HorizontalListView?hListView;??????HorizontalListViewAdapter?hListViewAdapter;??????ImageView?previewImg;??????View?olderSelectView?=?null;??????@Override??????protected?void?onCreate(Bundle?savedInstanceState)?{??????????super.onCreate(savedInstanceState);??????????setContentView(R.layout.activity_main);??????????initUI();??????}????????@Override??????public?boolean?onCreateOptionsMenu(Menu?menu)?{??????????//?Inflate?the?menu;?this?adds?items?to?the?action?bar?if?it?is?present.??????????getMenuInflater().inflate(R.menu.main,?menu);??????????return?true;??????}??????public?void?initUI(){??????????hListView?=?(HorizontalListView)findViewById(R.id.horizon_listview);??????????previewImg?=?(ImageView)findViewById(R.id.image_preview);??????????String[]?titles?=?{"懷師",?"南懷瑾軍校",?"閉關",?"南懷瑾",?"南公莊嚴照",?"懷師法相"};??????????final?int[]?ids?=?{R.drawable.nanhuaijin_miss,?R.drawable.nanhuaijin_school,??????????????????R.drawable.nanhuaijin_biguan,?R.drawable.nanhuaijin,??????????????????R.drawable.nanhuaijin_zhuangyan,?R.drawable.nanhuaijin_faxiang};??????????hListViewAdapter?=?new?HorizontalListViewAdapter(getApplicationContext(),titles,ids);??????????hListView.setAdapter(hListViewAdapter);??????????//??????hListView.setOnItemSelectedListener(new?OnItemSelectedListener()?{??????????//??????????//??????????@Override??????????//??????????public?void?onItemSelected(AdapterView??
HorizontalListView.java 這就是自定義的橫向listview
[java]
view plaincopyprint?package?org.yanzi.ui;????/*??*?HorizontalListView.java?v1.5??*??*???*?The?MIT?License??*?Copyright?(c)?2011?Paul?Soucy?(paul@dev-smart.com)??*???*?Permission?is?hereby?granted,?free?of?charge,?to?any?person?obtaining?a?copy??*?of?this?software?and?associated?documentation?files?(the?"Software"),?to?deal??*?in?the?Software?without?restriction,?including?without?limitation?the?rights??*?to?use,?copy,?modify,?merge,?publish,?distribute,?sublicense,?and/or?sell??*?copies?of?the?Software,?and?to?permit?persons?to?whom?the?Software?is??*?furnished?to?do?so,?subject?to?the?following?conditions:??*???*?The?above?copyright?notice?and?this?permission?notice?shall?be?included?in??*?all?copies?or?substantial?portions?of?the?Software.??*???*?THE?SOFTWARE?IS?PROVIDED?"AS?IS",?WITHOUT?WARRANTY?OF?ANY?KIND,?EXPRESS?OR??*?IMPLIED,?INCLUDING?BUT?NOT?LIMITED?TO?THE?WARRANTIES?OF?MERCHANTABILITY,??*?FITNESS?FOR?A?PARTICULAR?PURPOSE?AND?NONINFRINGEMENT.?IN?NO?EVENT?SHALL?THE??*?AUTHORS?OR?COPYRIGHT?HOLDERS?BE?LIABLE?FOR?ANY?CLAIM,?DAMAGES?OR?OTHER??*?LIABILITY,?WHETHER?IN?AN?ACTION?OF?CONTRACT,?TORT?OR?OTHERWISE,?ARISING?FROM,??*?OUT?OF?OR?IN?CONNECTION?WITH?THE?SOFTWARE?OR?THE?USE?OR?OTHER?DEALINGS?IN??*?THE?SOFTWARE.??*??*/??????import?java.util.LinkedList;??import?java.util.Queue;????import?android.content.Context;??import?android.database.DataSetObserver;??import?android.graphics.Rect;??import?android.util.AttributeSet;??import?android.view.GestureDetector;??import?android.view.GestureDetector.OnGestureListener;??import?android.view.MotionEvent;??import?android.view.View;??import?android.widget.AdapterView;??import?android.widget.ListAdapter;??import?android.widget.Scroller;????public?class?HorizontalListView?extends?AdapterView??
HorizontalListViewAdapter.java 橫向listview的適配器,我將他單獨寫到一個java文件里。
[java]
view plaincopyprint?package?org.yanzi.ui;????import?org.yanzi.testhorizontallistview.R;??import?org.yanzi.util.BitmapUtil;????import?android.content.Context;??import?android.graphics.Bitmap;??import?android.graphics.drawable.Drawable;??import?android.media.ThumbnailUtils;??import?android.view.LayoutInflater;??import?android.view.View;??import?android.view.ViewGroup;??import?android.widget.BaseAdapter;??import?android.widget.ImageView;??import?android.widget.TextView;????public?class?HorizontalListViewAdapter?extends?BaseAdapter{??????private?int[]?mIconIDs;??????private?String[]?mTitles;??????private?Context?mContext;??????private?LayoutInflater?mInflater;??????Bitmap?iconBitmap;??????private?int?selectIndex?=?-1;????????public?HorizontalListViewAdapter(Context?context,?String[]?titles,?int[]?ids){??????????this.mContext?=?context;??????????this.mIconIDs?=?ids;??????????this.mTitles?=?titles;??????????mInflater=(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);//LayoutInflater.from(mContext);??????}??????@Override??????public?int?getCount()?{??????????return?mIconIDs.length;??????}??????@Override??????public?Object?getItem(int?position)?{??????????return?position;??????}????????@Override??????public?long?getItemId(int?position)?{??????????return?position;??????}????????@Override??????public?View?getView(int?position,?View?convertView,?ViewGroup?parent)?{????????????ViewHolder?holder;??????????if(convertView==null){??????????????holder?=?new?ViewHolder();??????????????convertView?=?mInflater.inflate(R.layout.horizontal_list_item,?null);??????????????holder.mImage=(ImageView)convertView.findViewById(R.id.img_list_item);??????????????holder.mTitle=(TextView)convertView.findViewById(R.id.text_list_item);??????????????convertView.setTag(holder);??????????}else{??????????????holder=(ViewHolder)convertView.getTag();??????????}??????????if(position?==?selectIndex){??????????????convertView.setSelected(true);??????????}else{??????????????convertView.setSelected(false);??????????}????????????????????holder.mTitle.setText(mTitles[position]);??????????iconBitmap?=?getPropThumnail(mIconIDs[position]);??????????holder.mImage.setImageBitmap(iconBitmap);????????????return?convertView;??????}????????private?static?class?ViewHolder?{??????????private?TextView?mTitle?;??????????private?ImageView?mImage;??????}??????private?Bitmap?getPropThumnail(int?id){??????????Drawable?d?=?mContext.getResources().getDrawable(id);??????????Bitmap?b?=?BitmapUtil.drawableToBitmap(d);??//??????Bitmap?bb?=?BitmapUtil.getRoundedCornerBitmap(b,?100);??????????int?w?=?mContext.getResources().getDimensionPixelOffset(R.dimen.thumnail_default_width);??????????int?h?=?mContext.getResources().getDimensionPixelSize(R.dimen.thumnail_default_height);????????????????????Bitmap?thumBitmap?=?ThumbnailUtils.extractThumbnail(b,?w,?h);????????????????????return?thumBitmap;??????}??????public?void?setSelectIndex(int?i){??????????selectIndex?=?i;??????}??}?
下圖是一個item被選定后,另一個item獲得了焦點:
要點如下:
1、可以說這個HorizontalListView是完美的,但美中不足的并不是其他人說的不能點擊、晃動、加載不全的問題,而是這個橫向Listview的高度,如果你設成wrap_cotent那么將會占據整個屏幕,即使你將它適配器里的view的高度限制死,限制成很小,這個HorizontalListView的高度依然是全屏。本文代碼里,我把圖片縮略圖弄成100dip,所以把這個HorizontalListView的高度設為了150dip。
2、在適配器里,我填充了一個圖片,下面是文字。為了能讓瀏覽圖片時item有反應,搞了一個selector,它的用法詳見這里.
但一開始在點擊時完全沒有反應。