Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 安卓(Android)ViewPager+TabLayout實現圖片輪播效果

安卓(Android)ViewPager+TabLayout實現圖片輪播效果

編輯:關於Android編程

起因: 最近在做一個新聞APP,看到現在的新聞客戶端頂端都有個熱點新聞輪播。

思路:viewpager可以用來顯示圖片,並且可以提供滑動,15年(不知記錯沒)新出的TabLayout可以綁定ViewPager的Adapter來實現ViewPager與Tablayout的聯動效果,比如qq的下面菜單欄,微信的菜單欄,都可以這樣實現。而且我們可以通過兩種方式來實現TabLayout的圖片標題:

1.SpannableString 來實現圖文混排,混排方法(傳送門)。

2.使用自定義布局,布局中添加你想要顯示的內容,然後調用tablayout中tab的setCustomView(View view)或者setCustomView(int R_id)方法來設置顯示。

下面正題:

這裡我使用第二種方法來實現,至於為什麼用第二種(好吧其實是我使用第一種的時候遇到了一個不顯示的bug,當然第二種也遇到了,後面會提及,後來就沒改回第一種了,原理一樣)源碼在最後面有下載。

一。首先我們來准備圖片:

沒有選中的位置的提示圖片:

\

選中了之後的位置的提示圖片:

\

圖片都可以使用ps制作,很簡單。

 

二。然後我們來寫輪播界面的布局(老規矩,先代碼後解釋):




    


這裡解釋幾個點:

 

(1)translationZ屬性:為了讓Tablayout顯示在Viewpager的上方,不設置z值大於ViewPager的話,就顯示不出來了。

(2)tabMode屬性:為了不讓tablayout滑動(在內容超出控件寬度的時候裡面內容滑動從而造成顯示上的邏輯錯誤)。

(3)tabMinWidth屬性:

tabMaxWidth屬性:設置tab的最小值和最大值,來控制每個tab的寬度(先立個Flag)。

三。現在我們來為ViewPager的內容寫布局文件,這裡我們的內容有新聞圖片(覆蓋全頁面),新聞標題(位於左下角),

布局文件如下:

 




    
這裡設置了圖片為默認的占位圖片。可根據喜好設置。

 

四。既然我們要自定義tablayout的布局,那麼我們現在就來寫這個布局文件

布局很簡單,就一個ImageView,為了拉伸圖片到全部頁面,我們這裡設置他的background屬性而不是src屬性:

 





五。布局我們已經弄好了,接下來就是邏輯代碼了,我這裡使用繼承自Fragment是為了方便插入任何其他布局裡,我這裡插入的是首頁。

 

這裡插播一下布局中插入碎片(Fragment)的方法,老規矩:

 


注意上面的name屬性是必要的,用來指向Fragment的定義,其他的屬性和一般的一樣設置就可以了。

 

現在可以寫輪播的Fragment的代碼了(很簡單的邏輯,我就不解釋了,重要的地方有注釋):

 

package lunbo;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.icu.text.LocaleDisplayNames;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.WindowDecorActionBar;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ImageSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;

import java.util.ArrayList;

import NewsInfo.JUHE_NewsInfo;
import Static.StaticValue;
import Util.FileOP.FileStore;
import Util.NetWork;
import winter.zxb.smilesb101.winternews.R;

/**
 * 項目名稱:WinterNews
 * 類描述:圖片輪播類
 * 創建人:SmileSB101
 * 創建時間:2016/11/9 0009 07:36
 * 修改人:Administrator
 * 修改時間:2016/11/9 0009 07:36
 * 修改備注:
 */

public class viewPagerLuobo extends Fragment{
	private TabLayout mTablayout;
	private ViewPager mViewPager;
	private int selectNum;
	private int pageNum;
	private View view;
	private ArrayList<juhe_newsinfo> juhe_newsInfos = new ArrayList<>();
	private viewPagerAdapter mViewPageAdapter;
	private static final int GetNewsDown = 0;
	private static final int GetNewsError = -1;
	private Handler handler = new Handler(){
		@Override
		public void handleMessage(Message msg){
			super.handleMessage(msg);
			switch(msg.what)
			{
				case GetNewsDown:
					Log.i("設置輪播圖片顯示","handleMessage: ");
					showTopNews();
					break;
				case GetNewsError:
					break;
			}
		}
	};
	@Nullable
	@Override
	public View onCreateView(LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState){
		view = inflater.inflate(R.layout.lunbo_viewpager,container,false);
		selectNum = 0;
		pageNum = 3;
		getTopNews();
		return view;
	}
	private void getTopNews()
	{
		RequestQueue mrequeue = NetWork.getmRequestqueue(StaticValue.MainActivity);
		String utl = "http://v.juhe.cn/toutiao/index?top&key=2d89bbcc668f4ef02cade2b00d7d9265";
		StringRequest stringRequest = new StringRequest(utl,new Response.Listener<string>(){
			@Override
			public void onResponse(String s){
				Log.i("獲取到頭條","onResponse: ");
				juhe_newsInfos = FileStore.getJUHENews_List(s);
				handler.sendEmptyMessage(GetNewsDown);
			}
		},new Response.ErrorListener(){
			@Override
			public void onErrorResponse(VolleyError volleyError){
				handler.sendEmptyMessage(GetNewsError);
			}
		});
		mrequeue.add(stringRequest);
	}
	private void showTopNews()
	{
		mViewPager = (ViewPager)view.findViewById(R.id.luobo_viewpager);
		mViewPageAdapter = new viewPagerAdapter(getFragmentManager());
		mViewPager.setAdapter(mViewPageAdapter);
		setmTablayout();
	}
	private void setmTablayout()
	{
		mTablayout = (TabLayout)view.findViewById(R.id.luobo_tablayout);
		mTablayout.setupWithViewPager(mViewPager);
		//添加tab,這裡添加一開始顯示的圖片,重要代碼
		for(int i = 0;i<mviewpageadapter.getcount();i++) charsequence="" extends="" fragment="" fragmentmanager="" imageview="" int="" new="" override="" pre="" public="" return="" run:="" selectnum="selectNum%pageNum;" setmtablayout:="" tab="mTablayout.getTabAt(i);" tabimage="(ImageView)v.findViewById(R.id.Imageview);" tablayout.tab="" v="LayoutInflater.from(StaticValue.MainActivity).inflate(R.layout.luobo_tablayout,null);" view="" viewpageradapter="" void="" data-cke-pa-ontabselected:="">

獲取新聞數據接口是來自聚合網,

下面貼出輪播Viewpager中的內容Fragment:

package lunbo;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;

import NewsInfo.JUHE_NewsInfo;
import winter.zxb.smilesb101.winternews.R;

/**
 * 項目名稱:WinterNews
 * 類描述:輪播ViewPager中顯示的內容的Fragment
 * 創建人:SmileSB101
 * 創建時間:2016/11/9 0009 13:24
 * 修改人:Administrator
 * 修改時間:2016/11/9 0009 13:24
 * 修改備注:
 */

public class ImageFragment extends Fragment{
	private ImageView mImageView;
	private JUHE_NewsInfo juhe_newsInfo;
	private TextView title;
	Fragment context;
	public void setJuhe_newsInfo(JUHE_NewsInfo juhe_newsInfo)
	{
		this.juhe_newsInfo = juhe_newsInfo;
	}
	public ImageFragment(){
	}
	public static ImageFragment newInstence(JUHE_NewsInfo juhe_newsInfo)
	{
		ImageFragment imageFragment = new ImageFragment();
		imageFragment.setJuhe_newsInfo(juhe_newsInfo);
		return imageFragment;
	}

	@Nullable
	@Override
	public View onCreateView(LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState){
		View rootView = null;
		context = this;
		rootView = inflater.inflate(R.layout.image_layout,container,false);
		title = (TextView)rootView.findViewById(R.id.imageLayout_Title);
		mImageView = (ImageView)rootView.findViewById(R.id.imageLayout_Image);
		if(juhe_newsInfo!=null) {
			Glide.with(context)
					.load(juhe_newsInfo.getThumbnail_pic_s())
					.placeholder(R.mipmap.winter_news_place_hloder_pic)
					.error(R.mipmap.winter_news_error_pic)
					.into(new SimpleTarget(){
						@Override
						public void onResourceReady(GlideDrawable resource,GlideAnimation glideAnimation){
							//在這裡設置圖片背景(當GLide獲取完成圖片之後執行)
							mImageView.setBackground(resource);
						}
					});
			title.setText(juhe_newsInfo.getTitle());
		}
		else
		{
			Glide.with(context)
					.load(R.mipmap.winter_news_place_hloder_pic)
					.error(R.mipmap.winter_news_error_pic)
					.into(new SimpleTarget(){
						@Override
						public void onResourceReady(GlideDrawable resource,GlideAnimation glideAnimation){
							//在這裡設置圖片背景(當GLide獲取完成圖片之後執行)
							mImageView.setBackground(resource);
						}
					});
		}
		return rootView;
	}
}
圖片加載我使用的是Glide庫,詳細的使用方法(點擊開啟傳送門)。

下面說一下我遇到的bug,在包含tablayout的布局中,沒有設置tab的最大寬度值,導致數量多了之後看不到背景圖片(這麼簡單的問題,蝸居然改本來就是能用的代碼改了大半天!!後來突然想到改少tab數量會不會有效才發現問題所在,在這裡做個記錄,以防再次入坑。)

下面是截圖(可以看到效果已經實現了,但是tab間距太遠):

\

於是我們調整一下tablayout的padding值以及tabMaxWidth的值:

改變之後的tablayout如下:

 
這裡控件的寬度可以自己根據實際需求更改

注意必須三個padding和MaxWidth同時設置才能有如下效果,缺一不可!!

注意必須三個padding和MaxWidth同時設置才能有如下效果,缺一不可!!

注意必須三個padding和MaxWidth同時設置才能有如下效果,缺一不可!!

最後截圖,原諒我沒有截成gif。實在不會用咔咔截屏。。。。

如有問題,歡迎指正。

現在來看看效果:

\

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved