Android水平(橫向)翻頁列表,類似於水平方向的GridView,行列自定義,但要翻頁切換,考慮加載性能,當Item數據很多時加載和翻頁要流暢,翻頁時要有動畫效果,效果圖如下:
實現方式:
1:翻頁可用ViewPager來做,每頁內多行排列Item,考慮到翻頁切換數據和加載的速度不能嵌套GridView,直接使用View來顯示。
2:緩存被ViewPager銷毀的View,以此來提高當數據量很大時的系統資源消耗問題。
代碼實現如下:
1:最主要的是編寫一個自定義的PagerAdapter類,用來給ViewPager適配數據,默認情況下ViewPager會緩存相鄰兩頁面的View,我們定義一個List<View>用來緩存被destroy后的view,當ViewPager需要實例化一個新View用來顯示時,判斷是否有緩存的View,如果有則拿出來使用,如果沒有實例化一個新的view,寫一個Item的布局文件,這里每頁面10個,通過ViewHolder來處理各小Item,每次實例化新的頁面時給view設置當前頁10個item的數據(從List中獲得,判斷當前頁需要顯示的position,從List中取出相應的數據,最后一頁顯示不完的地方留空)。具體實現代碼如下:
/** * @author Homgwu */ public class MainViewPagerAdapter extends PagerAdapter implements OnClickListener { private List<ItemEntity> singerList = new ArrayList<ItemEntity>(); private Context mContext; private int pagerCount = 0; /** * 用來緩存被viewpager destroy掉的view,以便重復使用 */ private List<View> cacheViews = new ArrayList<View>(); private LayoutInflater mInflater; // private static final int TAG_VIEWHOLDER = 1; // private static final int TAG_ITEMDATA = 2; /** * 一頁內的item個數 */ private double itemInCount = 10.0; public MainViewPagerAdapter(List<ItemEntity> itemList, Context mContext) { super(); this.singerList = itemList; this.mContext = mContext; pagerCount = (int) Math.ceil(itemList.size() / itemInCount); mInflater = LayoutInflater.from(this.mContext); } public void updateData(List<ItemEntity> singerList) { this.singerList = singerList; notifyDataSetChanged(); } @Override public int getCount() { return pagerCount; } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public void destroyItem(ViewGroup container, int position, Object object) { View view = (View) object; ((ViewPager) container).removeView(view); //隱藏頁面內的item clearViewContent((ViewHolder) view.getTag()); //添加到緩存 cacheViews.add(view); } @Override public int getItemPosition(Object object) { return POSITION_NONE; } @Override public Object instantiateItem(ViewGroup container, int position) { View view = null; ViewHolder viewHolder = null; //沒有緩存的view時新建一個用來顯示 if (cacheViews.isEmpty()) { view = mInflater.inflate(R.layout.viewpager_item, container, false); viewHolder = new ViewHolder(view); view.setTag(viewHolder); } else { //有緩存的view時取出使用 view = cacheViews.remove(0); viewHolder = (ViewHolder) view.getTag(); } //設置頁面內的各item initItemData(viewHolder, view, position); container.addView(view); return view; } private void initItemData(ViewHolder viewHolder, View view, int position) { int totalInItemCount = singerList.size(); int tempitemInCount= (int) itemInCount; //每頁顯示10個item for (int i = 0; i < tempitemInCount; i++) { //計算當前頁要顯示的item在arraylist中的position。 int inItemPosition = position *tempitemInCount + i; //如果最后一頁顯示不滿時跳出循環,后面的item不再顯示 if (inItemPosition >= totalInItemCount) { break; } ItemEntity itemEntity = singerList.get(inItemPosition); switch (i) { case 0: viewHolder.bgIV1 .setBackgroundResource(R.mipmap.item_bg); viewHolder.titleTV1.setText(itemEntity.name); viewHolder.itemRL1.setVisibility(View.VISIBLE); viewHolder.itemRL1.setTag(itemEntity); viewHolder.itemRL1.setOnClickListener(this); break; case 1: viewHolder.bgIV2 .setBackgroundResource(R.mipmap.item_bg); viewHolder.titleTV2.setText(itemEntity.name); viewHolder.itemRL2.setVisibility(View.VISIBLE); viewHolder.itemRL2.setTag(itemEntity); viewHolder.itemRL2.setOnClickListener(this); break; case 2: viewHolder.bgIV3 .setBackgroundResource(R.mipmap.item_bg); viewHolder.titleTV3.setText(itemEntity.name); viewHolder.itemRL3.setVisibility(View.VISIBLE); viewHolder.itemRL3.setTag(itemEntity); viewHolder.itemRL3.setOnClickListener(this); break; case 3: viewHolder.bgIV4 .setBackgroundResource(R.mipmap.item_bg); viewHolder.titleTV4.setText(itemEntity.name); viewHolder.itemRL4.setVisibility(View.VISIBLE); viewHolder.itemRL4.setTag(itemEntity); viewHolder.itemRL4.setOnClickListener(this); break; case 4: viewHolder.bgIV5 .setBackgroundResource(R.mipmap.item_bg); viewHolder.titleTV5.setText(itemEntity.name); viewHolder.itemRL5.setVisibility(View.VISIBLE); viewHolder.itemRL5.setTag(itemEntity); viewHolder.itemRL5.setOnClickListener(this); break; case 5: viewHolder.bgIV6 .setBackgroundResource(R.mipmap.item_bg); viewHolder.titleTV6.setText(itemEntity.name); viewHolder.itemRL6.setVisibility(View.VISIBLE); viewHolder.itemRL6.setTag(itemEntity); viewHolder.itemRL6.setOnClickListener(this); break; case 6: viewHolder.bgIV7 .setBackgroundResource(R.mipmap.item_bg); viewHolder.titleTV7.setText(itemEntity.name); viewHolder.itemRL7.setVisibility(View.VISIBLE); viewHolder.itemRL7.setTag(itemEntity); viewHolder.itemRL7.setOnClickListener(this); break; case 7: viewHolder.bgIV8 .setBackgroundResource(R.mipmap.item_bg); viewHolder.titleTV8.setText(itemEntity.name); viewHolder.itemRL8.setVisibility(View.VISIBLE); viewHolder.itemRL8.setTag(itemEntity); viewHolder.itemRL8.setOnClickListener(this); break; case 8: viewHolder.bgIV9 .setBackgroundResource(R.mipmap.item_bg); viewHolder.titleTV9.setText(itemEntity.name); viewHolder.itemRL9.setVisibility(View.VISIBLE); viewHolder.itemRL9.setTag(itemEntity); viewHolder.itemRL9.setOnClickListener(this); break; case 9: viewHolder.bgIV10 .setBackgroundResource(R.mipmap.item_bg); viewHolder.titleTV10.setText(itemEntity.name); viewHolder.itemRL10.setVisibility(View.VISIBLE); viewHolder.itemRL10.setTag(itemEntity); viewHolder.itemRL10.setOnClickListener(this); break; default: break; } } } /** * 隱藏各item * @param viewHolder */ private void clearViewContent(ViewHolder viewHolder) { viewHolder.itemRL1.setVisibility(View.GONE); viewHolder.itemRL2.setVisibility(View.GONE); viewHolder.itemRL3.setVisibility(View.GONE); viewHolder.itemRL4.setVisibility(View.GONE); viewHolder.itemRL5.setVisibility(View.GONE); viewHolder.itemRL6.setVisibility(View.GONE); viewHolder.itemRL7.setVisibility(View.GONE); viewHolder.itemRL8.setVisibility(View.GONE); viewHolder.itemRL9.setVisibility(View.GONE); viewHolder.itemRL10.setVisibility(View.GONE); } @Override public void onClick(View arg0) { //點擊到對應item ItemEntity itemEntity = (ItemEntity) arg0.getTag(); Toast.makeText(mContext, itemEntity.name, Toast.LENGTH_SHORT).show(); } /** * viewHolder */ static class ViewHolder { public ImageView bgIV1, bgIV2, bgIV3, bgIV4, bgIV5, bgIV6, bgIV7, bgIV8, bgIV9, bgIV10; public TextView titleTV1, titleTV2, titleTV3, titleTV4, titleTV5, titleTV6, titleTV7, titleTV8, titleTV9, titleTV10; public RelativeLayout itemRL1, itemRL2, itemRL3, itemRL4, itemRL5, itemRL6, itemRL7, itemRL8, itemRL9, itemRL10; public ViewHolder(View itemView) { bgIV1 = (ImageView) itemView .findViewById(R.id.fragment_music_singer_item_image_iv_one); titleTV1 = (TextView) itemView .findViewById(R.id.fragment_music_singer_item_name_tv_one); bgIV2 = (ImageView) itemView .findViewById(R.id.fragment_music_singer_item_image_iv_two); titleTV2 = (TextView) itemView .findViewById(R.id.fragment_music_singer_item_name_tv_two); bgIV3 = (ImageView) itemView .findViewById(R.id.fragment_music_singer_item_image_iv_three); titleTV3 = (TextView) itemView .findViewById(R.id.fragment_music_singer_item_name_tv_three); bgIV4 = (ImageView) itemView .findViewById(R.id.fragment_music_singer_item_image_iv_four); titleTV4 = (TextView) itemView .findViewById(R.id.fragment_music_singer_item_name_tv_four); bgIV5 = (ImageView) itemView .findViewById(R.id.fragment_music_singer_item_image_iv_five); titleTV5 = (TextView) itemView .findViewById(R.id.fragment_music_singer_item_name_tv_five); bgIV6 = (ImageView) itemView .findViewById(R.id.fragment_music_singer_item_image_iv_six); titleTV6 = (TextView) itemView .findViewById(R.id.fragment_music_singer_item_name_tv_six); bgIV7 = (ImageView) itemView .findViewById(R.id.fragment_music_singer_item_image_iv_seven); titleTV7 = (TextView) itemView .findViewById(R.id.fragment_music_singer_item_name_tv_seven); bgIV8 = (ImageView) itemView .findViewById(R.id.fragment_music_singer_item_image_iv_eight); titleTV8 = (TextView) itemView .findViewById(R.id.fragment_music_singer_item_name_tv_eight); bgIV9 = (ImageView) itemView .findViewById(R.id.fragment_music_singer_item_image_iv_nine); titleTV9 = (TextView) itemView .findViewById(R.id.fragment_music_singer_item_name_tv_nine); bgIV10 = (ImageView) itemView .findViewById(R.id.fragment_music_singer_item_image_iv_ten); titleTV10 = (TextView) itemView .findViewById(R.id.fragment_music_singer_item_name_tv_ten); itemRL1 = (RelativeLayout) itemView .findViewById(R.id.fragment_music_singer_item_one); itemRL2 = (RelativeLayout) itemView .findViewById(R.id.fragment_music_singer_item_two); itemRL3 = (RelativeLayout) itemView .findViewById(R.id.fragment_music_singer_item_three); itemRL4 = (RelativeLayout) itemView .findViewById(R.id.fragment_music_singer_item_four); itemRL5 = (RelativeLayout) itemView .findViewById(R.id.fragment_music_singer_item_five); itemRL6 = (RelativeLayout) itemView .findViewById(R.id.fragment_music_singer_item_six); itemRL7 = (RelativeLayout) itemView .findViewById(R.id.fragment_music_singer_item_seven); itemRL8 = (RelativeLayout) itemView .findViewById(R.id.fragment_music_singer_item_eight); itemRL9 = (RelativeLayout) itemView .findViewById(R.id.fragment_music_singer_item_nine); itemRL10 = (RelativeLayout) itemView .findViewById(R.id.fragment_music_singer_item_ten); } } }
2:ViewPager使用:
/** * @author Homgwu */ public class MainActivity extends Activity { private ViewPager mViewPager; private MainViewPagerAdapter mViewPagerAdapter; private List<ItemEntity> mItemEntityList=new ArrayList<ItemEntity>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView(){ mViewPager= (ViewPager) findViewById(R.id.main_vp); initData(); mViewPagerAdapter=new MainViewPagerAdapter(mItemEntityList,this); //設置翻頁動畫 mViewPager.setPageTransformer(true,new DepthPageTransformer()); mViewPager.setAdapter(mViewPagerAdapter); } /** * 初始化數據 */ private void initData(){ for (int i=0;i<104;i++){ ItemEntity itemEntity=new ItemEntity(); itemEntity.name="Android"+i; mItemEntityList.add(itemEntity); } } }
3:動畫代碼:
public class DepthPageTransformer implements PageTransformer { private static float MIN_SCALE = 0.5f; /** * position參數指明給定頁面相對於屏幕中心的位置。它是一個動態屬性,會隨着頁面的滾動而改變。當一個頁面填充整個屏幕是,它的值是0, * 當一個頁面剛剛離開屏幕的右邊時 * ,它的值是1。當兩個也頁面分別滾動到一半時,其中一個頁面的位置是-0.5,另一個頁面的位置是0.5。基於屏幕上頁面的位置 * ,通過使用諸如setAlpha()、setTranslationX()、或setScaleY()方法來設置頁面的屬性,來創建自定義的滑動動畫。 */ @Override public void transformPage(View view, float position) { int pageWidth = view.getWidth(); if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left. view.setAlpha(0); view.setTranslationX(0); } else if (position <= 0) { // [-1,0] // Use the default slide transition when // moving to the left page view.setAlpha(1); view.setTranslationX(0); view.setScaleX(1); view.setScaleY(1); } else if (position <= 1) { // (0,1] // Fade the page out. view.setAlpha(1 - position); // Counteract the default slide transition view.setTranslationX(pageWidth * -position); // Scale the page down (between MIN_SCALE and 1) float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0); view.setScaleX(1); view.setScaleY(1); } } }
完整Sample可以到如下地址下載:
1:http://download.csdn.net/detail/homg92/8584445