Android進階練習-自訂視圖實戰之重新整理等待進度條

來源:互聯網
上載者:User
         實現一個最簡單的自訂視圖(不包含處理使用者的觸摸事件),往往只需要三步
     一、繼承自一個View(可以是一個更具體的Android已實現好的View),並增加必須的構造方法(這個根據自訂View怎麼使用來判斷)
     二、覆寫onDraw(Canvas canvas)方法,並且自訂繪製     三、重繪,分為即時重繪和屬性更新重繪

     自訂視圖如果是繼承自原始View的話,public View(android.content.Context context)這個構造方法是必須的。而public View(android.content.Context context, android.util.AttributeSet attrs)這個構造方法是可選,但如果你想在xml布局檔案中使用自訂視圖的話,帶屬性的建構函式也是必須的,因為Android系統是根據這個建構函式去執行個體化視圖的,這樣也可以讓我們的視圖可視化,配置的屬性值也能夠根據它來獲得     關於自訂繪製,需要注意的是Android架構已經為我們提供了很多的方法來繪製各種圖元,直接使用就行了,要記住的是自訂視圖並不會自己主動的去重繪自己,首次顯示會繪製一次,往往需要我們去通知它進行重繪,可以在視圖上調用invalidate()和postInvalidate()來通知重繪,兩者的區別稍後會進行解釋     重繪,有些視圖往往需要即時的進行重繪,像一些即時性很強的遊戲,但這個一般需要使用到SurfaceView,有興趣的話可以去學習下,我們今天的例子也需要進行即時重繪,但沒有使用到SurfaceView,而是繼承於View。有的時候可能並不需要即時進行重繪,像只有在改變了視圖的一個屬性值的情況下才需要重新繪製,這個時候我們可以在setXX()方法中調用invalidate()方法就行

下面是一個等待進度條的例子

package tu.bingbing.customdialogview.view;import tu.bingbing.customdialogview.R;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.view.View;public class CustomDialogView extends View {        // 載入圖片資源id,存入緩衝數組        private final int[] ids = new int[] { R.drawable. loading01,                    R.drawable. loading02, R.drawable.loading03, R.drawable.loading04 ,                    R.drawable. loading05, R.drawable.loading06, R.drawable.loading07 ,                    R.drawable. loading08, R.drawable.loading09, R.drawable.loading10 ,                    R.drawable. loading11 };        private Bitmap[] loadingImgs ;        private Paint loadingImagePaint ;        private int currentIdsIndex = 0;        public CustomDialogView(Context context, AttributeSet attrs) {              super(context, attrs);             init();       }        public CustomDialogView(Context context) {              super(context);             init();       }        private void init() {                           // 執行個體化畫筆              loadingImagePaint = new Paint();              // 設定消除鋸齒              loadingImagePaint.setAntiAlias(true);              // 一次性放進緩衝數組中              loadingImgs = new Bitmap[] {                           BitmapFactory. decodeResource(getResources(), ids[0]),                           BitmapFactory. decodeResource(getResources(), ids[1]),                           BitmapFactory. decodeResource(getResources(), ids[2]),                           BitmapFactory. decodeResource(getResources(), ids[3]),                           BitmapFactory. decodeResource(getResources(), ids[4]),                           BitmapFactory. decodeResource(getResources(), ids[5]),                           BitmapFactory. decodeResource(getResources(), ids[6]),                           BitmapFactory. decodeResource(getResources(), ids[7]),                           BitmapFactory. decodeResource(getResources(), ids[8]),                           BitmapFactory. decodeResource(getResources(), ids[9]),                           BitmapFactory. decodeResource(getResources(), ids[10]) };       }        @Override        protected void onDraw(Canvas canvas) {              // 迴圈控制每一張圖片的繪製順序,讓看起來像是播放動畫              if (currentIdsIndex >= (ids .length - 1)) {                     currentIdsIndex = 0;             }             Bitmap currentLoadingBitmap = loadingImgs[currentIdsIndex ];              // 繪製圖片,顯示在螢幕正中             canvas.drawBitmap(currentLoadingBitmap, (getWidth() - currentLoadingBitmap.getWidth())/2,                           (getHeight() - currentLoadingBitmap.getHeight())/2, loadingImagePaint );              currentIdsIndex++;              super.onDraw(canvas);       }}

     在View上getWidth()和getHeight()方法取到的是螢幕的高和寬,BitmapFactory.decodeResource(Resources res,
int id)方法根據資源id得到一張位元影像用於顯示,關於是否應該把所有的圖片一次性的載入入記憶體,這個可以根據需要來定,你可以一次性全部載入,可以得到更流暢的UI,但更耗損記憶體;你也可以到在要用到的時候再載入,這樣可能會有一定的延遲,但可以有效節省記憶體;也可以使用軟引用來儲存圖片,這樣可以使得在程式記憶體不足時,圖片記憶體得以回收,兩全其美。

在Activity中即時重繪視圖

package tu.bingbing.customdialogview;import tu.bingbing.customdialogview.view.CustomDialogView;import android.os.Bundle;import android.app.Activity;import android.view.Menu;public class MainActivity extends Activity {        private CustomDialogView customDialogView ;        private RedrawCustomDialogViewThread redrawCdvRunnable ;               @Override        protected void onCreate(Bundle savedInstanceState) {              super.onCreate(savedInstanceState);                          setContentView(R.layout. activity_main);                           customDialogView = (CustomDialogView) findViewById(R.id.view_customdialog );              redrawCdvRunnable = new RedrawCustomDialogViewThread();              new Thread(redrawCdvRunnable ).start();       }        @Override        public boolean onCreateOptionsMenu(Menu menu) {              // Inflate the menu; this adds items to the action bar if it is present.             getMenuInflater().inflate(R.menu. main, menu);              return true ;       }               final class RedrawCustomDialogViewThread implements Runnable{              private boolean isRun = true;                           @Override              public void run() {                     while(isRun ){                            try {                                 Thread. sleep(100);                           } catch (InterruptedException e) {                                 e.printStackTrace();                           }                            // 通知重繪                            customDialogView.postInvalidate();                    }                                 }              public boolean isRun() {                     return isRun ;             }              public void setRun(boolean isRun) {                     this.isRun = isRun;             }                                 }        @Override        protected void onDestroy() {                           redrawCdvRunnable.setRun(false );                           super.onDestroy();       }}

布局檔案
<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:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity" >        <tu.bingbing.customdialogview.view.CustomDialogView         android:id="@+id/view_customdialog"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        />    </RelativeLayout>

     除了使用postInvalidate()方法外,還可以使用invalidate()方法,前者讓程式可以在UI主線程外的線程中去通知視圖進行重繪,後者必須在UI主線程中進行調用通知,一般可以和Handler一起使用

使用到的圖片資源

程式運行效果

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.