android代碼實現ViewPager的indictor效果

來源:互聯網
上載者:User

          今天無聊自己寫了一個模仿viewpager的指標,這個例子是利用我以前寫的一片文章的例子進行改進《android橫向滾動螢幕特效分析》。

          下面說下我的思路,首先當控制項初始化的時候擷取ScrollLayout空間的子View控制項個數,然後傳入我們要寫的IndictorView類裡面,然後利用onDraw()方法在螢幕上畫同等數量的圓形,表示當前螢幕的圓圈我們用不同的顏色區分就行了,然後每次移動的時候我們改變畫表示當前螢幕圓圈的位置即可。

          既然要畫兩種顏色的圓圈那麼就要產生兩種顏色的畫筆,下面是我產生畫筆的代碼:

/** * 產生標識當前螢幕的畫筆和背景圓圈的畫筆,此方法在構造方法中調用 */private void init() {// 這句是讓畫筆畫得更細膩(消除鋸齒)fontPaint = new Paint(Paint.ANTI_ALIAS_FLAG);// 這句話的意思是已填充的方式畫園,Style.STROKE方式是畫一個圓環中間沒有填充fontPaint.setStyle(Style.FILL);// 設定畫筆的顏色fontPaint.setColor(Color.RED);backPaint = new Paint(Paint.ANTI_ALIAS_FLAG);backPaint.setStyle(Style.FILL);backPaint.setColor(Color.BLACK);}

        在構造好IndictorView之後我們需要把ScorllView的子項目個數傳過來,那麼就需要提供一個方法讓外部可以把我們需要的資料傳如,下面是實現代碼:

/** * 初始化圓的個數,這裡的螢幕寬度是為了後面我們計算圓圈的位置時使用 *  * @param circleNumber *            園的數量 * @param motionWidth *            螢幕的寬度 */public void init(int circleNumber, float motionWidth) {this.circleNumber = circleNumber;this.motionWidth = motionWidth;}

        現在我們有了園的個數,又得到螢幕的寬度,那麼就可以開始畫園了,下面是實現代碼:

@Overridepublic void draw(Canvas canvas) {// 得到圓的Y軸座標int height = getHeight() - getPaddingTop() - (radius * 2);// 這裡是根據需要畫圓的個數使用一個迴圈遍曆來畫園for (int i = 1; i <= circleNumber; i++) {// 噹噹前的圓的下標等於要畫的園的下標時候,說明這個下標就是標識當前螢幕下標的園if (curentCircleNumber == i) {// 這裡的運算式主要是計算園的X軸座標canvas.drawCircle((motionWidth - (radius * 2* (circleNumber - i) + (circlePadding * (circleNumber- i - 1)))) / 2.0f + 10, height, radius, fontPaint);} else {// 畫背景圓圈canvas.drawCircle((motionWidth - (radius * 2* (circleNumber - i) + (circlePadding * (circleNumber- i - 1)))) / 2.0f + 10, height, radius, backPaint);}}super.draw(canvas);// 重新整理螢幕invalidate();}

      上面就是核心代碼,那麼有人會問當OnDraw()執行過後怎樣改變圓圈的位置能,其實View的onDraw()方法是在這個view被渲染後一直在後台執行的,所以不同擔心我們改變curentCircleNumber的值時會不會從繪圓的位置的問題。

      最後大家別忘了一件事,我們在重寫空間的時候一定要記得覆蓋onMeasure()方法,這裡就不多說了,下面是源碼:

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec));}private int measureWidth(int measureSpec) {int result = 0;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);// 當控制項設定全屏時if (specMode == MeasureSpec.EXACTLY) {result = specSize;} else {float temp = circleNumber - 2 * radius;result = (int) (getPaddingLeft() + getPaddingRight()+ (circleNumber * 2 * radius) + (circleNumber - 1) * temp + 1);// 當設定根據內容自動適應if (specMode == MeasureSpec.AT_MOST) {result = Math.min(result, specSize);}}return result;}private int measureHeight(int measureSpec) {int result = 0;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);// 當空間設定全屏時if (specMode == MeasureSpec.EXACTLY) {result = specSize;} else {result = (int) (4 * radius + getPaddingTop() + getPaddingBottom() + 1);// 當設定根據內容自動適應if (specMode == MeasureSpec.AT_MOST) {result = Math.min(result, specSize);}}return result;}

           這時我們的IndictorView類我們就完全寫好了,下面是我的布局檔案menu.xml:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent" >    <cn.com.karl.scrollview.ScrollLayout        android:id="@+id/scorllView"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:background="@android:color/white" >        <ImageView            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:scaleType="fitCenter"            android:src="@drawable/test1" />        <ImageView            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:scaleType="fitCenter"            android:src="@drawable/test2" />        <ImageView            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:scaleType="fitCenter"            android:src="@drawable/test3" />        <ImageView            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:scaleType="fitCenter"            android:src="@drawable/test1" />            </cn.com.karl.scrollview.ScrollLayout>    <LinearLayout        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_alignBottom="@+id/scorllView"        android:background="#88252525" >        <cn.com.karl.scrollview.IndictorView            android:id="@+id/indictorView"            android:layout_width="fill_parent"            android:layout_height="wrap_content"            android:layout_gravity="center" />    </LinearLayout></RelativeLayout>

          這裡值得注意的是android:background="#88252525"這個背景色是為了給我們的IndictorView控制項加上透明背景色,這個可以選擇性添加。

         下面是主程式使用源碼:

package cn.com.karl.activity;import android.app.Activity;import android.os.Bundle;import android.view.Display;import cn.com.karl.R;import cn.com.karl.scrollview.IndictorView;import cn.com.karl.scrollview.ScrollLayout;public class TestScrollLayout extends Activity {private ScrollLayout scrollLalyout;private IndictorView indictorView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.menu);initView();}private void initView() {scrollLalyout = (ScrollLayout) findViewById(R.id.scorllView);indictorView = (IndictorView) findViewById(R.id.indictorView);Display display = getWindowManager().getDefaultDisplay();indictorView.init(scrollLalyout.getChildCount(), display.getWidth());scrollLalyout.setIndictorView(indictorView);}}

           scrollLalyout.setIndictorView(indictorView);這一句是把我們的指標放到ScrollLayout裡面去,當螢幕移動的時候可以調用我們的IndictorView的setCurentCircleNumber()方法來時時改變下標.

          下面是ScrollLayout裡面的移動螢幕的方法源碼:

/** * 移動到下一個螢幕 *  * @param whichScreen *            下一個螢幕的下標識 */public void snapToScreen(int whichScreen) {// get the valid layout pagewhichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));if (getScrollX() != (whichScreen * getWidth())) {final int delta = whichScreen * getWidth() - getScrollX();mScroller.startScroll(getScrollX(), 0, delta, 0, 1000);mCurScreen = whichScreen;invalidate(); // Redraw the layoutindictorView.setCurentCircleNumber(whichScreen + 1);}}

 

           好了這裡就寫完了,有不足的地方請大家指正!下面是

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.