Android自定義控件(實(shí)現(xiàn)視圖樹繪制指示器)
之前寫輪播條或者指示器的時(shí)候都是UI圖里面直接有,這樣的效果并不好,給用戶的體驗(yàn)比較差,所以閑暇之余自己寫了個(gè)指示器,可以展現(xiàn)出一個(gè)優(yōu)雅的效果,當(dāng)手指 當(dāng)手指滑動(dòng)的時(shí)候小圓點(diǎn)會(huì)跟著一點(diǎn)一點(diǎn)的滑動(dòng),當(dāng)手指停下時(shí),小紅點(diǎn)也跟著停下來。首先我說說我實(shí)現(xiàn)的這個(gè)原理吧
首先在布局文件里面寫上線性布局,表示底部的小圓點(diǎn),方向和位置,然后再在shape里面自繪小圓點(diǎn)。再在代碼里面里用布局寫出,具體步驟如下:
1、使用LayParams給布局里面添加未選中的小圓點(diǎn),例如灰色;
2、設(shè)置小紅點(diǎn),表示滑動(dòng)后的狀態(tài)。
3、獲取小圓點(diǎn)之間的距離,這里要獲取小圓點(diǎn)的距離不能簡單地getWidth,getHeiget,這樣是獲取不到的 ,這里要用到視圖樹來觀察兩個(gè)點(diǎn)距離左側(cè)屏幕之間的距離,然后求差獲取距離。
4、在監(jiān)聽viewpager的時(shí)候獲取兩者的距離。
代碼如下:
一、布局文件
<!--小紅點(diǎn),小圓點(diǎn)的滑動(dòng),具體布局在代碼里面寫的--> <?xml version="1.0" encoding="utf-8"?> <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"> <android.support.v4.view.ViewPager android:id="@+id/vp_pager" android:layout_width="match_parent" android:layout_height="match_parent"/> <Button android:id="@+id/btn_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="60dp" android:background="#FFF107" android:paddingLeft="10dp" android:paddingRight="10dp" android:textSize="20sp" android:text="開始體驗(yàn)" android:visibility="gone"/> <!--小紅點(diǎn),小圓點(diǎn)的滑動(dòng),具體布局在代碼里面寫的--> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="20dp"> <LinearLayout android:id="@+id/ll_point_group" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> </LinearLayout> <View android:id="@+id/view_red_point" android:layout_width="10dp" android:layout_height="10dp" android:background="@drawable/shape_guide_point_selected"/> </RelativeLayout> </RelativeLayout> <!--普通的圓點(diǎn)--> <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > <solid android:color="@android:color/darker_gray" /> </shape> <!--小紅點(diǎn)的圓點(diǎn)--> <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > <solid android:color="#f00" /> </shape>
二、代碼
/** * 初始化viewpager的數(shù)據(jù) */ private void initView() { int[] icons = {R.mipmap.guide1,R.mipmap.guide2,R.mipmap.guide3,R.mipmap.guide4}; mList = new ArrayList<>(); for (int i = 0; i < icons.length; i++) { ImageView view = new ImageView(this); view.setBackgroundResource(icons[i]); //只有設(shè)置了背景才能填充滿屏幕 mList.add(view); //設(shè)置,灰色的小圓點(diǎn),表示滑動(dòng)時(shí)候的狀態(tài) View point = new View(this); point.setBackgroundResource(R.drawable.shape_guide_point_default); //設(shè)置背景 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(DensityUtils.dp2px(this,10), DensityUtils.dp2px(this,10)); point.setLayoutParams(params); if (i != 0) { params.leftMargin = DensityUtils.dp2px(this, 10); } llpointGroup.addView(point); } }
三、獲取小紅點(diǎn)之間的距離
/** * 初始化小紅點(diǎn)之間的距離 */ private void initPoint() { // measure -> layout -> draw viewRedPoint.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { //完成布局后回調(diào)該方法,該方法有可能被多次回調(diào) @Override public void onGlobalLayout() { viewRedPoint.getViewTreeObserver().removeGlobalOnLayoutListener(this); mPointWidth = llpointGroup.getChildAt(1).getLeft() - llpointGroup.getChildAt(0).getLeft(); } }); }
四、讓小紅點(diǎn)聯(lián)動(dòng)
/** * viewpager的頁面滑動(dòng)的監(jiān)聽 */ private void initScrollListen() { viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { //當(dāng)頁面被滑動(dòng)的時(shí)候 //參數(shù)一:當(dāng)前頁面的位置 參數(shù)二:偏移的百分比 參數(shù)三:偏移的距離 @Override public void onPageScrolled(int position,float positionOffset,int positionOffsetPixels) { int leftMargin = (int) (mPointWidth * (position + positionOffset)); RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewRedPoint.getLayoutParams(); lp.leftMargin = leftMargin; viewRedPoint.setLayoutParams(lp); } //當(dāng)頁面被選擇 @Override public void onPageSelected(int position) { } //當(dāng)頁面狀態(tài)改變的時(shí)候 @Override public void onPageScrollStateChanged(int state) { } }); }
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
Android開發(fā)實(shí)現(xiàn)高仿優(yōu)酷的客戶端圖片左右滑動(dòng)切換功能實(shí)例【附源碼下載】
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)高仿優(yōu)酷的客戶端圖片左右滑動(dòng)切換功能,結(jié)合實(shí)例形式分析了Android基于ViewPager實(shí)現(xiàn)圖片切換效果的相關(guān)操作技巧,并附帶完整工程源碼供讀者下載參考,需要的朋友可以參考下2017-11-11Android adb.exe程序啟動(dòng)不起來 具體解決方法
這篇文章主要介紹了Android adb.exe程序啟動(dòng)不起來 具體解決方法,有需要的朋友可以參考一下2013-12-12TextView實(shí)現(xiàn)圖文混合編排的方法
這篇文章主要為大家詳細(xì)介紹了TextView實(shí)現(xiàn)圖文混合編排的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08Android JNI c/c++調(diào)用java的實(shí)例
這篇文章主要介紹了Android JNI c/c++調(diào)用java的實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-07-07Android如何通過手機(jī)自動(dòng)獲取短信驗(yàn)證碼
注冊(cè)帳號(hào)時(shí),經(jīng)常需要手機(jī)獲取驗(yàn)證碼,Android如何通過手機(jī)自動(dòng)獲取短信驗(yàn)證碼,下面看看小編給大家分享的一段代碼,感興趣的小伙伴們可以參考一下2016-03-03Android實(shí)現(xiàn)一個(gè)簡單的單詞本
大家好,本篇文章主要講的是Android實(shí)現(xiàn)一個(gè)簡單的單詞本,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01android中設(shè)置TextView/Button 走馬燈(Marquee)效果示例
定義走馬燈(Marquee),主要在Project/res/layout/main.xml即可,下面與大家分享下具體的實(shí)現(xiàn),感興趣的朋友可以參考下哈2013-06-06Android 調(diào)用系統(tǒng)照相機(jī)拍照和錄像
本文主要介紹Android 調(diào)用系統(tǒng)照相機(jī)拍照和錄像的資料,這里整理了詳細(xì)的代碼,有需要的小伙伴可以參考下2016-09-09android 開發(fā)教程之日歷項(xiàng)目實(shí)踐(二)
決定開始學(xué)習(xí) Android 平臺(tái)下的軟件開發(fā),以日歷作為實(shí)踐項(xiàng)目,進(jìn)行一周后,基本完成,有需要的朋友可以參考下2013-01-01