2015年4月5日 星期日

視窗超出螢幕時如何移動視窗

今天發生一個非常窘的事情,就是打Android Studio打開的手機模擬器(AVD : android vertiual device)視窗太大超出螢幕,上面的選單那列完全被擋住了,無法用滑鼠去點來移動,雖然是一個小問題就也突然讓我愣了一下不知道該怎麼辦,上網查了一下才發現原來早就有好多人碰到也解決了,只是我今天才碰到,算是孤陋寡聞了,所以在這簡單地紀錄一下解決的方法:


  1. 選取超出螢幕的視窗。
  2. 用鍵盤按下 alt-space(空白鍵),會出現視窗的選單。
  3. 在選單中按下移動後,就可以用鍵盤的方向鍵或滑鼠移到想要的位置放置。
下面是一些找到的參考資料:

  1. 視窗跑到螢幕外 該怎麼辦?
  2. 視窗 超出螢幕 消失 無法移動視窗 (使用鍵盤移動視窗)

Android的手勢判斷 : GestureDetector

GestureDetctor是Android的一個手勢判斷用的類別,它讓開發者可以更容易、方便地判斷手勢的各種動作,包括有下列等等:

  1. onSingleTapUp : 按一下(按下並放開)。
  2. onLongPress : 長按(按下不放開)。
  3. onScroll : 捲動、捲動(按下移動沒有放開)。
  4. onFling :  滑動(按下移動並放開)。
  5. onShowPress : 按住(按下沒放開)。
  6. onDown : 按下。
  7. onDoubleTap : 按兩下(算一次事件)。
  8. onDoubleTapEvent : 按兩下(算兩次事件)。
  9. onSingleTapConfirmed : 確定按一下。
在這篇Android觸摸事件onScroll和onFling特別重要啊,要區分裡有對各項動作做了較為清楚的說明,也寫出了事件發生的順序及由何種動作觸發。


下面我們就寫一個簡單的程式碼來試試看各種動作的觸發狀況:

2015年4月1日 星期三

Android的動態桌布 - Wallpaper

在Android中可以製作動態桌布,動態桌布是一個類似動畫的桌布,上面可以顯示動畫,甚或可以與使用者產生互動。

下面以一個範例來實作一個簡單的動態桌布,桌布背景為黑色, 當使用者點擊或劃過桌布時,會產生藍色的圓,並且隨時間變小消失:

  1. 建立WallpaperService。動態桌布其實也是一種Service,使用的class為WallpaperService,所以我們要先建立WallpaperService類別,程式碼如下,需要注意的是,在WallpaperService裡的Engine內部類別不行在WallpaperService之外建立然後使用,必須是也內部類別的方式存在在WallpaperService中:

  2. MyWallpaperService.java:
    package com.example.administrator.wallpaperservice_example;
    
    import android.service.wallpaper.WallpaperService;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
    
    public class MyWallpaperService extends WallpaperService{
        @Override
        public Engine onCreateEngine() {
            return new MyEngine();
        }
    
        //設定自訂的Engine
        class MyEngine extends Engine{
            WallpaperThread wallpaperThread;
            public MyEngine() {
                SurfaceHolder surfaceHolder = getSurfaceHolder();
                wallpaperThread = new WallpaperThread(surfaceHolder);
            }
    
            @Override
            public void onCreate(SurfaceHolder surfaceHolder) {
                super.onCreate(surfaceHolder);
                //設定動態桌布可以互動觸控事件
                setTouchEventsEnabled(true);
            }
    
            @Override
            public void onSurfaceCreated(SurfaceHolder holder) {
                super.onSurfaceCreated(holder);
                //開始執行動態桌布
                wallpaperThread.start();
            }
    
            @Override
            public void onSurfaceDestroyed(SurfaceHolder holder) {
                super.onSurfaceDestroyed(holder);
                //結束動態桌布
                wallpaperThread.stopRunning();
            }
    
            @Override
            public void onDestroy() {
                super.onDestroy();
                //讓GC回收wallpaperThread
                wallpaperThread = null;
            }
    
            @Override
            public void onTouchEvent(MotionEvent event) {
                super.onTouchEvent(event);
                //執行wallpaperThread裡的觸控事件
                wallpaperThread.doTouchEvent(event);
            }
        }
    }

2015年3月28日 星期六

Android中的各種Adapter View (ListView、Spinner、與Gallery)

Android中有一種類型的View,其都繼承了AdapterView類,都使用Adapter來當做顯示與資料之間的橋梁。ListView、Spinner、和Gallery是非常常見的三種AdapterView元件,在這裡我將實做簡單的ListView、Spinner、和Gallery範例,並從程式碼讓大家觀察到它們的實做程式碼有多麼的相似,在學習時應當一同學習而不是把每個元件都當成一個全新的元件來學習,方可增加學習的效率與理解。

  1. 首先,我們先為三種不同的AdapterView建立共同使用來顯示資料的Layout:
  2. my_base_adapter_layout.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    
        android:orientation="horizontal" android:layout_width="match_parent"
    
        android:layout_height="match_parent"
    
        android:gravity="center_vertical">
    
    
        <ImageView
    
            android:layout_width="50dp"
    
            android:layout_height="50dp"
    
            android:id="@+id/imageView" />
    
    
        <TextView
    
            android:layout_width="wrap_content"
    
            android:layout_height="wrap_content"
    
            android:textAppearance="?android:attr/textAppearanceLarge"
    
            android:text="Large Text"
    
            android:id="@+id/textView" />
    
    
    </LinearLayout>
    
    
  3. 在這裡,我在res資料夾中設置了arrays.xml,紀錄了圖片資源的名稱:
  4. <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <string-array name="pictrueNames">
            <item>菊花</item>
            <item>沙漠</item>
            <item>繡球花</item>
            <item>水母</item>
        </string-array>
    
    </resources>
    
    
    
    
  5. 再來,為展示三種不同AdapterView的Activity建立它們各自的Layout,其中都各自在右下角有一個按鈕,用來切換到不同的Activity:

2015年3月26日 星期四

Android的畫廊 - Gallery與ImageSwitcher

Android有提供Gallery及ImageSwitcher的控件,結合這個兩個控件可以很容易地做出一個簡單的小畫廊。

Gallery:

  1. 可以配合Adapter,將圖片的資放進Adapter中,在用Gallery的setAdapter()方法就可以讓Gallery能夠顯示相應的圖片,其中還可以配合OnItemSelectedListener來取得是哪一張圖片被Select。
  2. 在這裡所謂被Select是指哪一張圖案在Gallery的正中央。
  3. 記得Gallery要設置Spacing的屬性,圖片才不會擠在一起。

ImageSwitcher:

  1. ImageSwitcher可以容易的切換兩張ImageView,並且可以為切換圖片的動作設定動畫(Animation)。
  2. 當呼叫ImageSwitcher的setImageResource()方法時,ImageSwitcher其實是設定好下一個ImageView再切換到下一個ImageView。
  3. 在使用ImageSwitcher時要用setFactory()方法設定ViewFactory,而ViewFactory要Override一個makeView()方法並回傳一個ImageView,也就是ImageSwitcher要用來顯示圖的ImageView。
  4. 對於ImageSwitcher的細節原理,在這篇Android_TextSwitcher和ImageSwitcher有非常詳盡的解說。
下面我就用程式碼來製作一個小型簡單的畫廊來做示範:

2015年3月24日 星期二

Android的小工具(App Widget)

App Widget就是我們很常見到的Android桌面小工具,要製App Widget需要有一些步驟,這裡也一個有三個按鈕的小工具來做示範:

  1. 製作要給小工具用的Layout,程式碼如下所示

  2. appwidgetlayout.xml :
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <Button
            android:id="@+id/buttonToToast"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="按下後跳出訊息(Toast)" />
    
        <Button
            android:id="@+id/buttonToNotify"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="按下後發送通知(Notification)" />
    
        <Button
            android:id="@+id/buttonToOpenActivity"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="按下後前往另一個Activity" />
    
    </LinearLayout>
    

2015年3月19日 星期四

用Matlab與Arduino的序列阜溝通

Arduino可以以序列阜(Serial Port)的方式與電腦溝通,只要雙方設置好對應的Baud Rate即可,電腦有許多種選擇,不管是什麼程式語言,只要找到能夠跟序列阜溝通的方法,就能夠以序列阜的方式跟Arduino溝通。

之前的一篇有介紹到以Java來跟Arduino溝通,這篇是要介紹使用Matlab的方式。

在網上搜查之後,找到了兩種主要的常見方法,可以參考這篇文,寫得非常詳細:
【經驗分享】Matlab和Arduino
,其中也寫到了如何用Simulink來跟Arduino溝通。

兩種主要的方法為:
1.使用Matlab Arduino Support package。
2.使用Matlab本身的指令去跟Serial Port連接。

第一種方法在【經驗分享】Matlab和Arduino有詳細的解說,要把其所附的程式燒錄到Arduino枚子上,然後用Matlab只接控制Arduino,使用方便,但其缺點為Arduino上不行燒錄自己所寫的Arduino程式,可以把它想成把原來在Arduino上寫的程式全部搬到了Matlab上面去執行。

在這裡我主要介紹第二種方法,此方法不用任何套件,單純就Matlab本身去跟Seriao Port去溝通。