Android矢量繪圖應用開發

yn6e 9年前發布 | 27K 次閱讀 Android Android開發 移動開發

練習1:超簡單的涂鴉App

準備工作:安裝 ADT Bundle 開發環境(我用的是v23,官方下載被墻,可從下載)。

  1. 新建 Android 程序項目。

    a. SDK 最小版本選 API 16 以上(避免自動創建的 appcompat_v7 項目出現資源缺失錯誤),完成后可改回低版本(使用 TouchVG 要求最低 API 12)。

    b. 在創建 Activity 頁面選擇默認的簡單布局 Blank Activity。

  2. 在主頁面布局中添加一個 FrameLayout,將用作繪圖區的容器。

    a. 指定 ID 為container,下面就可通過findViewById(R.id.container)找到此布局。

    b. 使用 FrameLayout 而不是其他布局類型做繪圖視圖容器,是避免觸摸繪圖引起其他相鄰視圖聯鎖刷新。

  3. 添加 TouchVG 引用。

    a. 下載預編譯的TouchVG包,將 touchvg.jar 和 libtouchvg.so 復制到程序項目的 libs 下。

    b. 如需調試進入 TouchVG 或快速查看 IViewHelper 接口注釋,則不能復制touchvg.jar,可將 TouchVG項目 復制到上級目錄并導入TouchVG工程,在程序項目的 project.properties 中加入引用:

    android.library.reference.1=../TouchVG

  4. 在 MainActivity.java 中創建繪圖視圖。

    a. 定義 IViewHelper 對象,在 onCreate 中創建繪圖視圖。

        public class MainActivity extends Activity {
          private IViewHelper mHelper = ViewFactory.createHelper();
    
          @Override
          protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_main);
    
             mHelper.createGraphView(this, (ViewGroup) this.findViewById(R.id.container));
             mHelper.setCommand("splines");
          }

    b. 在createGraphView下一行的setCommand激活隨手畫命令。splines是命令名,更多命令名見在線文檔

    c. 將createGraphView換為createSurfaceView可基于 SurfaceView 創建繪圖視圖,適合大量圖形或頁面上有較多控件的情況。在普通 View 上繪圖時占用主線程顯示,刷新時可能引起頁面其他視圖被動刷新。在 SurfaceView 上可異步繪圖,避免連鎖刷新問題。

  5. 運行程序,動手畫圖吧。

    step1

練習2:添加繪圖按鈕

  1. 添加按鈕布局和按鈕圖片。

    在 res/drawable 中添加五個按鈕圖片,在 res/layout 中添加按鈕布局 button_bar.xml:

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="wrap_content"
         android:layout_height="fill_parent"
         android:orientation="vertical" >
    
         <ImageButton
            android:id="@+id/line_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/line" />
    
         <ImageButton
            android:id="@+id/select_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/select" />
    
      </LinearLayout>

    主界面布局 activity_main.xml:

      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/horzLayout"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="horizontal" >
    
          <include
             android:id="@+id/buttons_bar"
             layout="@layout/buttons_bar" />
    
          <FrameLayout
             android:id="@+id/container"
             android:layout_width="match_parent"
             android:layout_height="match_parent" >
          </FrameLayout>
    
      </LinearLayout>

  2. 添加按鈕響應,激活相應繪圖命令。

      @Override
      protected void onCreate(Bundle savedInstanceState) {
         .....
         initButtons();
      }
    
      private void initButtons() {
         findViewById(R.id.line_btn).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mHelper.setCommand("line");
            }
         });
         findViewById(R.id.select_btn).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mHelper.setCommand("select");
            }
         });
      }

  3. 再次運行程序,點按鈕可繪制多種圖形。但選擇圖形出來幾個空的按鈕。

    step2

  4. 添加上下文按鈕資源、本地化串資源。從預編譯的TouchVG包中,將 res/drawable-hdpi、res/drawable-mdpi、res/values 合并到程序中。其中 res/values/strings.xml 不能直接復制文件,需要合并文字內容。

    step3

練習3:增加自動保存和恢復功能

目前重啟程序或按Home鍵,返回程序后所繪圖形會丟失。可以增加自動保存和恢復功能。

  1. 在 AndroidManifest.xml 中增加 MOUNT_UNMOUNT_FILESYSTEMS 和 WRITE_EXTERNAL_STORAGE 權限,以便讀寫外部存儲器。

  2. 在 MainActivity 中實現 onDestroy、onPause、onSaveInstanceState、onRestoreInstanceState,分別調用 IViewHelper 中相似名稱的函數。在創建繪圖視圖時傳入 savedInstanceState,返回 Activity 時自動恢復圖形:mHelper.createGraphView(this, layout, savedInstanceState);。

練習4:增加線寬動態修改和更新功能

選中一個圖形,可動態(所見即所得)修改其線寬等屬性。沒有選中圖形時設置的圖形屬性將應用到新畫的圖形上。

  1. 在 Activity 布局中增加一個滑塊控件,ID為lineWidthBar,最大值為 20,即最大20像素寬。

  2. 在 MainActivity 的 onCreate 中設置滑動響應:

     mLineWidthBar = (SeekBar) findViewById(R.id.lineWidthBar);
     mLineWidthBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            mHelper.setStrokeWidth(progress);
        }
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            mHelper.setContextEditing(true);
        }
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            mHelper.setContextEditing(false);
        }
     });

    其中,調用 setContextEditing 是避免在拖動滑塊過程中多次提交改動,產生多次Undo步驟(下面會實現Undo)。

  3. 為了在選中不同的圖形后更新線寬滑塊值,需要增加選擇改變觀察者

    mHelper.getGraphView().setOnSelectionChangedListener(new OnSelectionChangedListener() {
        @Override
        public void onSelectionChanged(IGraphView view) {
            mLineWidthBar.setProgress(mHelper.getStrokeWidth());
        }
    });

練習5:增加顏色選擇框

  1. 在工程中導入Android-Color-Picker庫。這里就直接添加源碼(com.chiralcode.colorpicker)了。也可以換為其他顏色選取框項目,例如 HoloColorPicker

  2. 增加一個按鈕,點擊時顯示顏色選擇對話框:

    findViewById(R.id.colorpicker_btn).setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
           new ColorPickerDialog(MainActivity.this, mHelper.getLineColor(),
               new OnColorSelectedListener() {
                   @Override
                   public void onColorSelected(int color) {
                       mHelper.setLineColor(color);
                   }
           }).show();
       }
    });

練習6:增加Undo/Redo功能

  1. 在頁面布局中增加兩個按鈕,ID為 undo_btn 和 redo_btn。

  2. 在按鈕點擊響應中執行Undo/Redo操作,并準備錄制Undo信息:

     findViewById(R.id.undo_btn).setOnClickListener(new OnClickListener() {
         @Override
         public void onClick(View v) {
             mHelper.undo();
         }
     });
     findViewById(R.id.redo_btn).setOnClickListener(new OnClickListener() {
         @Override
         public void onClick(View v) {
             mHelper.redo();
         }
     });
     mHelper.startUndoRecord(PATH + "undo");

  3. 增加圖形內容改變的觀察者,在圖形改變時更新按鈕狀態:

    mHelper.getGraphView().setOnContentChangedListener(new OnContentChangedListener() {
       @Override
       public void onContentChanged(IGraphView view) {
           findViewById(R.id.undo_btn).setEnabled(mHelper.canUndo());
           findViewById(R.id.redo_btn).setEnabled(mHelper.canRedo());
       }
    });

所有源碼已在GitHub開放,歡迎試驗評論。

來自:http://my.oschina.net/rhcad/blog/395596

 本文由用戶 yn6e 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!