2018.9.27補Github項目java
https://github.com/luhuan97/ImageCarouselandroid
優化了不少,可是我半年不寫安卓了,今晚花了兩個小時弄了出來。git
------------------------------------------------------------------------github
我在看別人文章的時候,最喜歡先找圖看。緩存
那我就先上效果圖:app
實現了圖片自動輪播,手動滑動,輪播標題,以及點擊事件。下面開始:ide
首先是佈局:佈局
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="xyz.ncvt.viewpagerdemo.MainActivity"> <FrameLayout android:layout_width="0dp" android:layout_height="200dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" tools:layout_editor_absoluteY="0dp" tools:layout_editor_absoluteX="8dp"/> <LinearLayout android:weightSum="10" android:background="#33000000" android:orientation="horizontal" android:layout_gravity="bottom" android:gravity="center_vertical" android:layout_width="match_parent" android:layout_height="35dip"> <TextView android:layout_weight="8" android:id="@+id/tv_pager_title" android:text="很長的標題。。。。。你懂我意思吧" android:paddingLeft="8dip" android:gravity="center_vertical" android:textColor="@color/white" android:layout_width="0dp" android:layout_height="35dip"/> <!--用來動態添加輪播小點--> <LinearLayout android:id="@+id/lineLayout_dot" android:layout_weight="2" android:gravity="center|right" android:layout_marginRight="5dp" android:paddingLeft="3dp" android:paddingRight="3dp" android:orientation="horizontal" android:layout_width="0dp" android:layout_height="match_parent"> </LinearLayout> </LinearLayout> </FrameLayout> </android.support.constraint.ConstraintLayout>
輪播小點資源(Drawable):這個是vector,你們能夠自行搜索瞭解。學習
<vector android:height="5dp" android:viewportHeight="24.0" android:viewportWidth="24.0" android:width="5dp" xmlns:android="http://schemas.android.com/apk/res/android"> <path android:fillColor="#fff" android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/> </vector>
建立一個圖片ID資源文件,用於圖片點擊事件:存放在values文件夾內優化
<?xml version="1.0" encoding="utf-8"?> <resources> <item name="pager_image1" type="id" /> <item name="pager_image2" type="id" /> <item name="pager_image3" type="id" /> <item name="pager_image4" type="id" /> </resources>
import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import java.util.List; public class ViewPagerAdapter extends PagerAdapter { private List<ImageView> images; private ViewPager viewPager; /** * 構造方法,傳入圖片列表和ViewPager實例 * @param images * @param viewPager */ public ViewPagerAdapter(List<ImageView> images, ViewPager viewPager){ this.images = images; this.viewPager = viewPager; } @Override public int getCount() { return Integer.MAX_VALUE;//返回一個無限大的值,能夠 無限循環 } /** * 判斷是否使用緩存, 若是返回的是true, 使用緩存. 不去調用instantiateItem方法建立一個新的對象 */ @Override public boolean isViewFromObject(View view, Object object) { return view == object; } /** * 初始化一個條目 * @param container * @param position 當前須要加載條目的索引 * @return */ @Override public Object instantiateItem(ViewGroup container, int position) { // 把position對應位置的ImageView添加到ViewPager中 ImageView iv = images.get(position % images.size()); viewPager.addView(iv); // 把當前添加ImageView返回回去. return iv; } /** * 銷燬一個條目 * position 就是當前須要被銷燬的條目的索引 */ @Override public void destroyItem(ViewGroup container, int position, Object object) { // 把ImageView從ViewPager中移除掉 viewPager.removeView(images.get(position % images.size())); }
public class MainActivity extends AppCompatActivity { private ViewPager mViewPager; private TextView mTvPagerTitle; private List<ImageView> mImageList;//輪播的圖片集合 private String[] mImageTitles;//標題集合 private int previousPosition = 0;//前一個被選中的position private List<View> mDots;//小點 private boolean isStop = false;//線程是否中止 private static int PAGER_TIOME = 5000;//間隔時間 // 在values文件假下建立了pager_image_ids.xml文件,並定義了4張輪播圖對應的id,用於點擊事件 private int[] imgae_ids = new int[]{R.id.pager_image1,R.id.pager_image2,R.id.pager_image3,R.id.pager_image4}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } /** * 第一步、初始化控件 */ public void init() { mViewPager = (ViewPager) findViewById(R.id.viewPager); mTvPagerTitle = (TextView) findViewById(R.id.tv_pager_title); initData();//初始化數據 initView();//初始化View,設置適配器 autoPlayView();//開啓線程,自動播放 } /** * 第二步、初始化數據(圖片、標題、點擊事件) */ public void initData() { //初始化標題列表和圖片 mImageTitles = new String[]{"這是一個好看的標題1","這是一個優美的標題2","這是一個快樂的標題3","這是一個開心的標題4"}; int[] imageRess = new int[]{R.drawable.ncvt_wifi_head,R.drawable.img1,R.drawable.img2,R.drawable.img3}; //添加圖片到圖片列表裏 mImageList = new ArrayList<>(); ImageView iv; for (int i = 0; i < mImageList.size(); i++) { iv = new ImageView(this); iv.setBackgroundResource(imageRess[i]);//設置圖片 iv.setId(imgae_ids[i]);//順便給圖片設置id iv.setOnClickListener(new pagerImageOnClick());//設置圖片點擊事件 mImageList.add(iv); } //添加輪播點 LinearLayout linearLayoutDots = (LinearLayout) findViewById(R.id.lineLayout_dot); mDots = addDots(linearLayoutDots,fromResToDrawable(this,R.drawable.ic_dot_normal),mImageList.size());//其中fromResToDrawable()方法是我自定義的,目的是將資源文件轉成Drawable } //圖片點擊事件 private class pagerImageOnClick implements View.OnClickListener{ @Override public void onClick(View v) { switch (v.getId()) { case R.id.pager_image1: Toast.makeText(MainActivity.this, "圖片1被點擊", Toast.LENGTH_SHORT).show(); break; case R.id.pager_image2: Toast.makeText(MainActivity.this, "圖片2被點擊", Toast.LENGTH_SHORT).show(); break; case R.id.pager_image3: Toast.makeText(MainActivity.this, "圖片3被點擊", Toast.LENGTH_SHORT).show(); break; case R.id.pager_image4: Toast.makeText(MainActivity.this, "圖片4被點擊", Toast.LENGTH_SHORT).show(); break; } } } /** * 第三步、給PagerViw設置適配器,並實現自動輪播功能 */ public void initView(){ ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(mImageList, mViewPager); mViewPager.setAdapter(viewPagerAdapter); mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { //僞無限循環,滑到最後一張圖片又重新進入第一張圖片 int newPosition = position % mImageList.size(); // 把當前選中的點給切換了, 還有描述信息也切換 mTvPagerTitle.setText(mImageTitles[newPosition]);//圖片下面設置顯示文本 //設置輪播點 LinearLayout.LayoutParams newDotParams = (LinearLayout.LayoutParams) mDots.get(newPosition).getLayoutParams(); newDotParams.width = 24; newDotParams.height = 24; LinearLayout.LayoutParams oldDotParams = (LinearLayout.LayoutParams) mDots.get(previousPosition).getLayoutParams(); oldDotParams.width = 16; oldDotParams.height = 16; // 把當前的索引賦值給前一個索引變量, 方便下一次再切換. previousPosition = newPosition; } @Override public void onPageScrollStateChanged(int state) { } }); setFirstLocation(); } /** * 第四步:設置剛打開app時顯示的圖片和文字 */ private void setFirstLocation() { mTvPagerTitle.setText(mImageTitles[previousPosition]); // 把ViewPager設置爲默認選中Integer.MAX_VALUE / t2,從十幾億次開始輪播圖片,達到無限循環目的; int m = (Integer.MAX_VALUE / 2) % mImageList.size(); int currentPosition = Integer.MAX_VALUE / 2 - m; mViewPager.setCurrentItem(currentPosition); } /** * 第五步: 設置自動播放,每隔PAGER_TIOME秒換一張圖片 */ private void autoPlayView() { //自動播放圖片 new Thread(new Runnable() { @Override public void run() { while (!isStop){ runOnUiThread(new Runnable() { @Override public void run() { mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1); } }); SystemClock.sleep(PAGER_TIOME); } } }).start(); } /** * 資源圖片轉Drawable * @param context * @param resId * @return */ public Drawable fromResToDrawable(Context context, int resId) { return context.getResources().getDrawable(resId); } /** * 動態添加一個點 * @param linearLayout 添加到LinearLayout佈局 * @param backgount 設置 * @return */ public int addDot(final LinearLayout linearLayout, Drawable backgount) { final View dot = new View(this); LinearLayout.LayoutParams dotParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); dotParams.width = 16; dotParams.height = 16; dotParams.setMargins(4,0,4,0); dot.setLayoutParams(dotParams); dot.setBackground(backgount); dot.setId(View.generateViewId()); linearLayout.addView(dot); return dot.getId(); } /** * 添加多個輪播小點到橫向線性佈局 * @param linearLayout * @param backgount * @param number * @return */ public List<View> addDots(final LinearLayout linearLayout, Drawable backgount, int number){ List<View> dots = new ArrayList<>(); for (int i = 0; i < number; i++) { int dotId = addDot(linearLayout,backgount); dots.add(findViewById(dotId)); } return dots; }
誒呀,感受有90%完美了,供你們學習參考。我優化一下代碼,再上demo。