android使用ViewPager實(shí)現(xiàn)圖片自動(dòng)切換
本文實(shí)現(xiàn)viewpager圖片輪播的功能、左右滑動(dòng)的時(shí)候能夠流暢的切換圖片、并且沒(méi)有邊界限制
1、activity_main.xml布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <RelativeLayout android:id="@+id/my_viewpager" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>
因?yàn)槲业腣iewPager是繼承RelativeLayout
2、layout_recommend_item.xml中的布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/iv_pic" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@mipmap/ic_launcher" android:layout_weight="1"/> <TextView android:id="@+id/tv_desc" android:text="123" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
ImageView是顯示圖片 TextView用來(lái)顯示每一個(gè)pager的標(biāo)題
3、MyViewPager類,因?yàn)閳D個(gè)方便,把能夠?qū)崿F(xiàn)這個(gè)功能否合成一個(gè)類、這樣用起來(lái)比較方便
import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Handler; import android.os.Message; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import java.util.ArrayList; import java.util.List; public class MyViewPager extends RelativeLayout { private static final int START_SCROLL = 1; private static final int SCROLL_NEXT = 2; private static final int SHOW_TIME = 5000;//顯示時(shí)間 private List<String> mDatas = new ArrayList<>();//viewpager每一頁(yè)對(duì)應(yīng)的標(biāo)題 private ViewPager mPager; private Context mContext; private int mWidth, mHeight; //viewpager的寬高 private int mTitleHeight; //標(biāo)題高度 private TipView mTipView; //標(biāo)題對(duì)應(yīng)的view //在主ui中更新viewpager,也就是切換圖片 private static Handler sHandler = new Handler() { @Override public void handleMessage(Message msg) { int w = msg.what; ViewPager pager = (ViewPager) msg.obj; switch (w) { case START_SCROLL: pager.setCurrentItem(msg.arg1, true); break; case SCROLL_NEXT: pager.setCurrentItem(msg.arg1, true); break; } } }; /** * 構(gòu)造函數(shù) * @param context content * @param w 要顯示的viewpager的寬 * @param h 要顯示的viewpager的高 */ public MyViewPager(Context context, int w, int h) { super(context); mContext = context; mWidth = w; mHeight = h; initView(); //取得數(shù)據(jù) 左邊隨便取的 只是為了看起來(lái)有效果 // 對(duì)viewpager滑動(dòng)進(jìn)行監(jiān)聽(tīng) mPager.setOnPageChangeListener(new MOnPagerChangeListener()); init(); DisplayMetrics dm = mContext.getResources().getDisplayMetrics(); mTitleHeight = cm_DptoPx(48, dm); } /** * 對(duì)viewpager控件進(jìn)行繪制寬高 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { ViewGroup.LayoutParams vp = getLayoutParams(); if (vp != null) { vp.width = mWidth; vp.height = mHeight; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } /** * 把dp轉(zhuǎn)化成px */ public static int cm_DptoPx(int dp,DisplayMetrics dis){ return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, dis); } private void init() { getData(); } private void initView() { mPager = new ViewPager(mContext); RelativeLayout.LayoutParams rp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); addView(mPager, rp); } public void getData() { for (int i = 0; i < 4 ; i++){ mDatas.add(i,"viewpager"+i); } sHandler.postDelayed(new Runnable() { @Override public void run() { stopAnimation(); initTipView(); mPager.setAdapter(new RecommendAdapter()); mPager.setCurrentItem(10000 * mDatas.size()); } }, 2000); } /** * 刪除隊(duì)列中的消息 */ public void stopAnimation() { sHandler.removeMessages(START_SCROLL); sHandler.removeMessages(SCROLL_NEXT); } public void startAnimation() { if (mDatas.size() == 0) { return; } Message msg = sHandler.obtainMessage(START_SCROLL); msg.obj = mPager; msg.arg1 = (mPager.getCurrentItem() + 1);//取得后一張圖片 sHandler.sendMessageDelayed(msg, SHOW_TIME);//5秒后發(fā)送給ui線程 } /** * 對(duì)標(biāo)題view移動(dòng)的光標(biāo)初始化 */ private void initTipView() { if (mTipView == null) { RelativeLayout.LayoutParams rp = new RelativeLayout.LayoutParams(10, 10); rp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); rp.bottomMargin = mTitleHeight; mTipView = new TipView(mContext, mDatas.size()); addView(mTipView, rp); } else { mTipView.setCount(mDatas.size()); } } private class MOnPagerChangeListener implements ViewPager.OnPageChangeListener { private int curState; @Override public void onPageScrolled(int i, float v, int i1) { } @Override public void onPageSelected(int i) { //滑動(dòng)結(jié)束 sHandler.removeMessages(SCROLL_NEXT); sHandler.removeMessages(START_SCROLL); if(curState == ViewPager.SCROLL_STATE_DRAGGING){ return; } Message msg = sHandler.obtainMessage(SCROLL_NEXT); msg.arg1 = i + 1; msg.obj = mPager; sHandler.sendMessageDelayed(msg, SHOW_TIME); mTipView.setCurPostion(i % mDatas.size()); } @Override public void onPageScrollStateChanged(int i) { //正在滑動(dòng)時(shí) curState = i; if(i == ViewPager.SCROLL_STATE_DRAGGING){ //SCROLL_STATE_DRAGGING正在滑動(dòng) SCROLL_STATE_IDLE什么都沒(méi)有做 //SCROLL_STATE_SETTLING 滑動(dòng)完畢 stopAnimation(); }else { if(!(sHandler.hasMessages(START_SCROLL)&&sHandler.hasMessages(SCROLL_NEXT))){ startAnimation(); } } } } private class RecommendAdapter extends PagerAdapter { @Override public Object instantiateItem(ViewGroup container, int position) { Log.i("MyViewPager","instantiateItem "); int curPos = position % mDatas.size(); View view = View.inflate(mContext, R.layout.layout_recommend_item, null); ViewGroup.LayoutParams vp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); ImageView iv = (ImageView) view.findViewById(R.id.iv_pic); TextView tv = (TextView) view.findViewById(R.id.tv_desc); tv.setText(mDatas.get(curPos)); container.addView(view, vp); view.setTag(curPos); view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { } }); return view; } @Override public int getCount() { return Integer.MAX_VALUE; } @Override public boolean isViewFromObject(View view, Object o) { return view == o; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } } private class TipView extends View { private int mPadding; private int mCount; private int mCurPos; private Paint mNorPaint; private Paint mSelPaint; private int mHeight; public TipView(Context context, int count) { super(context); mNorPaint = new Paint(); mNorPaint.setAntiAlias(true); DisplayMetrics dm = context.getResources().getDisplayMetrics(); int selHeight = cm_DptoPx(2, dm); int norHeight = cm_DptoPx(1, dm); mHeight = cm_DptoPx(2, dm); mNorPaint.setStrokeWidth(norHeight); mNorPaint.setColor(Color.argb(80, 255, 255, 255)); mSelPaint = new Paint(); mSelPaint.setAntiAlias(true); mSelPaint.setStrokeWidth(selHeight); mSelPaint.setColor(Color.WHITE); mCount = count; mPadding = cm_DptoPx(0, dm); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int ow = (getWidth()-2*mPadding)/ mCount; int y = getHeight() / 2; canvas.drawLine(mPadding, y, mCurPos * ow + mPadding, y, mNorPaint); canvas.drawLine(mCurPos * ow + mPadding, y, (mCurPos + 1) * ow + mPadding, y, mSelPaint); canvas.drawLine((mCurPos + 1) * ow + mPadding, y, getWidth() - mPadding, y, mNorPaint); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { ViewGroup.LayoutParams vp = getLayoutParams(); vp.width = ViewGroup.LayoutParams.MATCH_PARENT; vp.height = mHeight; super.onMeasure(widthMeasureSpec, heightMeasureSpec); } public void setCurPostion(int pos) { mCurPos = pos; invalidate(); } public void setCount(int count) { mCount = count; } } }
4、還有MainActivity中的實(shí)現(xiàn)
import android.app.Activity; import android.os.Bundle; import android.util.DisplayMetrics; import android.widget.RelativeLayout; public class MainActivity extends Activity { private RelativeLayout mViewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DisplayMetrics dm = getResources().getDisplayMetrics(); mViewPager = (RelativeLayout) findViewById(R.id.my_viewpager); mViewPager.addView(new MyViewPager(getApplicationContext(),dm.widthPixels ,(dm.widthPixels)/2)); } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android 自定義圖片地圖坐標(biāo)功能的實(shí)現(xiàn)
最近項(xiàng)目要求實(shí)現(xiàn)一個(gè)在自定義地圖圖片上添加坐標(biāo)信息的功能,類似于在圖片做標(biāo)注的功能,這種功能糾結(jié)該如何實(shí)現(xiàn)呢?下面小編通過(guò)實(shí)例代碼給大家介紹Android 自定義地圖的實(shí)現(xiàn),需要的朋友參考下吧2021-07-07淺談Android IPC機(jī)制之Binder的工作機(jī)制
IPC機(jī)制即為跨進(jìn)程通信,是inter-Process Communication的縮寫(xiě)。是指兩個(gè)進(jìn)程之間進(jìn)行通信。在說(shuō)進(jìn)程通信之前,我們的弄明白什么是線程,什么是進(jìn)程。進(jìn)程和線程是兩個(gè)截然不同的概念。本文將介紹Android IPC機(jī)制之Binder的工作機(jī)制。2021-06-06完美解決android M上鎖屏情況下,禁止pc通過(guò)MTP訪問(wèn)手機(jī)存儲(chǔ)單元
下面小編就為大家?guī)?lái)一篇完美解決android M上鎖屏情況下,禁止pc通過(guò)MTP訪問(wèn)手機(jī)存儲(chǔ)單元。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04Flutter實(shí)現(xiàn)底部導(dǎo)航欄
這篇文章主要為大家詳細(xì)介紹了Flutter實(shí)現(xiàn)底部導(dǎo)航欄的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02Flutter中g(shù)o_router路由管理的使用指南
go_router?是一個(gè)?Flutter?的第三方路由插件,相比?Flutter?自帶的路由,go_router?更加靈活,而且簡(jiǎn)單易用,下面小編就來(lái)和大家聊聊go_router的使用吧2023-08-08Android Studio kotlin生成編輯類注釋代碼
這篇文章主要介紹了Android Studio kotlin生成編輯類注釋代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03Android ListView中動(dòng)態(tài)添加RaidoButton的實(shí)例詳解
這篇文章主要介紹了Android ListView中動(dòng)態(tài)添加RaidoButton的實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-08-08