最近工作不是很忙,也跟大神學習下總結一些小的技術點:
對于一個App幾乎都有Banner廣告功能,也就是我們常見的輪播圖,當然目前市場第三方框架已經非常成熟了,尤其是youth5201314/banner這里有github地址也可以學習下:https://github.com/youth5201314/banner.git
那么下面給大家介紹我的一些總結:
首先分析下輪播圖的設計
- 多張輪播圖定時效果
- 指示點以及每張圖片的文字說明
- 實現無限輪播,可滑動,圖片點擊事件
開始布局:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
< 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" tools:context = "com.yangziling.carousel.MainActivity" > <!--輪播圖--> < FrameLayout android:layout_width = "match_parent" android:layout_height = "200dp" > < android.support.v4.view.ViewPager android:id = "@+id/vp" android:layout_width = "match_parent" android:layout_height = "match_parent" /> <!--指示點和圖片標題--> < LinearLayout android:layout_width = "match_parent" android:layout_height = "35dip" android:layout_gravity = "bottom" android:background = "#33000000" android:gravity = "center" android:orientation = "vertical" > <!--圖片配文--> < TextView android:id = "@+id/title" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "圖片標題" android:textColor = "@android:color/white" /> < LinearLayout android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_marginTop = "3dip" android:orientation = "horizontal" > <!--指示點--> < View android:id = "@+id/dot_0" style = "@style/view_attr" android:background = "@drawable/dot_focused" /> < View android:id = "@+id/dot_1" style = "@style/view_attr" android:background = "@drawable/dot_normal" /> < View android:id = "@+id/dot_2" style = "@style/view_attr" android:background = "@drawable/dot_normal" /> < View android:id = "@+id/dot_3" style = "@style/view_attr" android:background = "@drawable/dot_normal" /> < View android:id = "@+id/dot_4" style = "@style/view_attr" android:background = "@drawable/dot_normal" /> </ LinearLayout > </ LinearLayout > </ FrameLayout > </ RelativeLayout > |
布局中抽取的view屬性:
1
2
3
4
5
6
|
< style name = "view_attr" > < item name = "android:layout_width" >5dp</ item > < item name = "android:layout_height" >5dp</ item > < item name = "android:layout_marginLeft" >5dp</ item > < item name = "android:layout_marginRight" >5dp</ item > </ style > |
這里我展示的一些圖片是在本地的,通過網絡框架加載圖片原理也是一樣的。
這里直接給大家貼出來核心代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
public class MainActivity extends AppCompatActivity { private ViewPager mMyViewPaper; private List<ImageView> images; private List<View> dots; private int currentItem; private TextView title; private MyAdapter adapter; //當前顯示圖片的位置 private int localPosition = 0 ; //圖片的id private int [] imageIds = new int []{R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e}; //圖片的標題 private String[] titles = new String[]{ "藍天白云" , "青山綠水" , "枯藤老樹" , "人間仙境" , "島嶼大樹" }; private TimerTask mTimerTask; //創建一個定時器 private final Timer timer = new Timer(); private ImageView mImageView; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMyViewPaper = (ViewPager) findViewById(R.id.vp); //顯示的圖片 images = new ArrayList<>(); for ( int i = 0 ; i < imageIds.length; i++) { mImageView = new ImageView( this ); mImageView.setBackgroundResource(imageIds[i]); images.add(mImageView); } //指示點 dots = new ArrayList<>(); dots.add(findViewById(R.id.dot_0)); dots.add(findViewById(R.id.dot_1)); dots.add(findViewById(R.id.dot_2)); dots.add(findViewById(R.id.dot_3)); dots.add(findViewById(R.id.dot_4)); title = (TextView) findViewById(R.id.title); title.setText(titles[ 0 ]); adapter = new MyAdapter(MainActivity. this , images); mMyViewPaper.setAdapter(adapter); mMyViewPaper.setOnPageChangeListener( new ViewPager.OnPageChangeListener() { @Override public void onPageSelected( int position) { position = position % images.size(); title.setText(titles[position]); dots.get(position).setBackgroundResource(R.drawable.dot_focused); dots.get(localPosition).setBackgroundResource(R.drawable.dot_normal); localPosition = position; currentItem = position; } /** * 頁面滑動時回調 */ @Override public void onPageScrolled( int arg0, float arg1, int arg2) { } /** * 當ViewPager狀態改變時,回調 */ @Override public void onPageScrollStateChanged( int state) { } }); } /** * 輪播任務 */ @Override protected void onStart() { super .onStart(); mTimerTask = new TimerTask() { @Override public void run() { currentItem = (currentItem + 1 ) % imageIds.length; mHandler.sendEmptyMessage( 0 ); } }; timer.schedule(mTimerTask, 2000 , 2000 ); } /** * 接收子線程傳遞的數據 */ private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { //輪播到最后一張圖片時,直接跳轉至第一頁,并且取消滑動效果 if (currentItem % images.size() == 0 ) { mMyViewPaper.setCurrentItem(currentItem, false ); } //非最后一張展示圖片的滑動效果 mMyViewPaper.setCurrentItem(currentItem, true ); } }; @Override protected void onStop() { super .onStop(); timer.cancel(); } } |
自定義了一個Adapter適配器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
public class MyAdapter extends PagerAdapter { private List<ImageView> images; private Context mContext; public MyAdapter(Context context,List<ImageView> images) { this .mContext =context; this .images = images; } //返回Viewpager中的view個數 @Override public int getCount() { return Integer.MAX_VALUE; } //判斷instantiateItem中的函數返回的key與一個頁面示圖是不是代表同一個 //通常直接相等就OK啦 @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } //移除一個固定位置的頁面 @Override public void destroyItem(ViewGroup view, int position, Object object) { view.removeView((View) object); } //將固定位置的View添加到Viewgroup中,并創建顯示出來 @Override public Object instantiateItem(ViewGroup view, final int position) { ImageView imageView = images.get(position % images.size()); ViewGroup parent = (ViewGroup) imageView.getParent(); //這里是動態添加示圖,一個子類只能有一個父類 //判斷下如果parent存在一定要記得移除 if (parent != null ) { parent.removeView(imageView); } view.addView(imageView); //給圖片添加點擊事件 imageView.setOnClickListener( new View.OnClickListener(){ @Override public void onClick(View v) { Toast.makeText(mContext, "點擊了第" +(position % images.size()+ 1 )+ "圖片" ,Toast.LENGTH_SHORT).show(); } }); return images.get(position % images.size()); } @Override public int getItemPosition(Object object) { return POSITION_NONE; } } |
在這里面也遇到一些問題,做了一些“妥協”,比如說無限輪播的時候發現播放到最后一張時會返回到第一張再次輪播,但是會有那種卡頓的感覺。所以我做了個“妥協的處理”,就是在播放到最后一張時,取消自帶的動畫效果,直接跳轉到第一張,然后進行輪播。
1
2
3
4
5
6
7
8
9
10
|
private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { //輪播到最后一張圖片時,直接跳轉至第一頁,并且取消滑動效果 if (currentItem % images.size() == 0 ) { mMyViewPaper.setCurrentItem(currentItem, false ); } //非最后一張展示圖片的滑動效果 mMyViewPaper.setCurrentItem(currentItem, true ); } }; |
項目的github地址:https://github.com/yangziling/Carousel.git
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://juejin.im/post/5a54a5a451882573443c908d