iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 26
1
Mobile Development

Android Studio 學習交流系列 第 26

[Day26]Android學習-創新挑戰-健康管理app(4)

  • 分享至 

  • xImage
  •  

這篇的專案內容如下:
/images/emoticon/emoticon13.gif

本篇重點

  1. 設計血壓紀錄頁面
  2. 設計血壓紀錄頁面的流程控制
  3. 客製化血壓紀錄選單

應具備能力

  1. Android學習-資料庫介紹-資料操縱(1)
  2. Android學習-資料庫介紹-SQLiteDataBase類別(2)
  3. Android學習-資料庫介紹-資料庫實作(3)
  4. Android學習-我的清單好朋友與baseAdapter類別

製作專案

這篇將介紹如何應用baseAdapter類別完成客製化的選單,以及建立一個layout配置ListView元件呈現資料庫所存取的資料,並且綜合Android學習-創新挑戰-健康管理app(3)所建立的HealthDB類別提供資料庫的操縱。

pressure_list.xml

完整程式碼

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:text="血壓管理"
            android:textSize="25dp"/>

        <ListView
            android:id="@+id/pressureList"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp" >

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:elevation="16dp"
            android:text="@string/float_text"
            android:textColor="#FFFFFF"
            android:textSize="25dp" />
    </FrameLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
  • CoordinatorLayout 是一layout提供子view彼此交互作用,這裡是Linearlayout上黏了一FloatingActionButton,隨著ListView的滑動FloatingActionButton固定相同位置。

  • bottom|end 意旨右下方

  • FrameLayout 使各個元件都在相同位置

  • Floating Action Button隨著ListView的滑動仍然固定在頁面右下方。相關問題參見如何新增Floating Action Button如何設計Floating Action Button

  • android:elevation 元件在Z軸的深度,以指出螢幕為+Z方向,指入螢幕為-Z方向

Pressure_view.xml

客製化設計屬於自己的選項排版方式
完整程式碼

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/txtDate"
        android:layout_width="140dp"
        android:layout_height="wrap_content"
        android:text="10/05"
        android:textSize="50dp" />
    <TextView
        android:id="@+id/txtHigh"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/txtDate"
        android:layout_marginLeft="5dp"
        android:textSize="25dp"
        android:text="收縮壓" />
    <TextView
        android:id="@+id/txtLow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/txtDate"
        android:layout_below="@+id/txtHigh"
        android:layout_marginLeft="5dp"
        android:layout_alignRight="@+id/txtHigh"
        android:textSize="25dp"
        android:text="舒張壓" />
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_alignParentRight="true"
        android:layout_marginTop="5dp"
        android:layout_marginRight="5dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/txtHigh"
            android:layout_gravity="center_horizontal"
            android:textSize="15dp"
            android:text="脈搏" />
        <TextView
            android:id="@+id/txtBump"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:textSize="30dp"
            android:text="100" />
    </LinearLayout>

</RelativeLayout>
  • 建立自己的選單內容:時間、收縮壓、舒張壓、脈搏等

PressureActivity.java

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pressure_list);
        setTitle("血壓管理");
        findViews();
        db=new HealthDB(PressureActivity.this);
        db.open();
        cursor=db.select_all();
        UpdateListView(cursor);
    }
  • cursor=db.select_all();與UpdateListView(cursor);開啟app時查詢資料庫所有資料並更新至ListView
 pressureList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position, long id) {
                try{
                    cursor.moveToPosition(position);
                    final int _id=Integer.parseInt(cursor.getString(0));
                    String date=cursor.getString(1);
                    String high=cursor.getString(2);
                    String low=cursor.getString(3);
                    new AlertDialog.Builder(PressureActivity.this)
                            .setMessage("確定刪除\nID="+id+"\n日期"+date+"\n收縮壓="
                                    +high+"\n舒張壓="+low)
                            .setPositiveButton("確認", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    //                    執行刪除動作
                                    db.delete(cursor.getInt(0));
                                    //                    更新顯示畫面
                                    UpdateListView(cursor=db.select_all());

                                }
                            })
                            .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {

                                }
                            })
                            .show();
                }catch (Exception e){
                    Toast.makeText(PressureActivity.this,"刪除失敗",Toast.LENGTH_LONG).show();
                }
                return false;
            }
        });
  • setOnItemLongClickListener 偵聽使用者是否長按選項
  • AlertDialog 跳出訊息與選項
  • 長按選項後,詢問是否刪除此選項
fab.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
          Intent intent =new Intent(PressureActivity.this,PressureCreateActivity.class);
          startActivity(intent);
    }
});
  • fab.setOnClickListener 偵聽使用者是否觸發FloatActionBar
  • startActivity 開啟新頁面
    public void UpdateListView(Cursor pressurecursor){
        MyAdapter adapter =new MyAdapter(pressurecursor);
        pressureList.setAdapter(adapter);
        cursor=pressurecursor;
    }
  • 建立UpdateListView()方法更新選單


    public class MyAdapter extends BaseAdapter {
        private Cursor cursor;
        public MyAdapter(Cursor cursor){
            this.cursor=cursor;
        }
        @Override
        public int getCount() {
            return cursor.getCount();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            cursor.moveToPosition(position);
            return cursor.getInt(0);
        }

        @Override
        public View getView(int position, View view, ViewGroup viewGroup) {
            View getview=view;
            cursor.moveToPosition(position);
            getview=getLayoutInflater().inflate(R.layout.pressure_view,null);
            TextView txtDate=(TextView)getview.findViewById(R.id.txtDate);
            txtDate.setText(cursor.getString(1));
            TextView txtHigh=(TextView)getview.findViewById(R.id.txtHigh);
            txtHigh.setText("收縮壓"+cursor.getString(2));
            TextView txtLow=(TextView)getview.findViewById(R.id.txtLow);
            txtLow.setText("舒張壓"+String.valueOf(cursor.getString(3)));
            return getview;
        }
    }

完整程式碼

public class PressureActivity extends AppCompatActivity {
    private HealthDB db;
    private Cursor cursor;
    private ListView pressureList;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pressure_list);
        setTitle("血壓管理");
        //        尋找各個元件的ID
        findViews();
        //        建立HealthDB物件db
        db=new HealthDB(PressureActivity.this);
        //        查詢目前資料庫擁有的資料
        db.open();
        cursor=db.select_all();
        //        更新ListView重新顯示資料
        UpdateListView(cursor);
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        //        尋找各個元件的ID
        findViews();
        //        建立FruitDB物件db
        db=new HealthDB(PressureActivity.this);
        //        查詢目前資料庫擁有的資料
        db.open();
        cursor=db.select_all();
        //        更新ListView重新顯示資料
        UpdateListView(cursor);
    }

    private void findViews() {
        pressureList=(ListView)findViewById(R.id.pressureList);
        pressureList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position, long id) {
                try{
                    cursor.moveToPosition(position);
                    final int _id=Integer.parseInt(cursor.getString(0));
                    String date=cursor.getString(1);
                    String high=cursor.getString(2);
                    String low=cursor.getString(3);
                    new AlertDialog.Builder(PressureActivity.this)
                            .setMessage("確定刪除\nID="+id+"\n日期"+date+"\n收縮壓="
                                    +high+"\n舒張壓="+low)
                            .setPositiveButton("確認", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    //                    執行刪除動作
                                    db.delete(cursor.getInt(0));
                                    //                    更新顯示畫面
                                    UpdateListView(cursor=db.select_all());

                                }
                            })
                            .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {

                                }
                            })
                            .show();
                }catch (Exception e){
                    Toast.makeText(PressureActivity.this,"刪除失敗",Toast.LENGTH_LONG).show();
                }
                return false;
            }
        });
        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent =new Intent(PressureActivity.this,PressureCreateActivity.class);
                startActivity(intent);
            }
        });

    }
    public void UpdateListView(Cursor pressurecursor){
        MyAdapter adapter =new MyAdapter(pressurecursor);
        pressureList.setAdapter(adapter);
        cursor=pressurecursor;
    }


    public class MyAdapter extends BaseAdapter {
        private Cursor cursor;
        public MyAdapter(Cursor cursor){
            this.cursor=cursor;
        }
        @Override
        public int getCount() {
            return cursor.getCount();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            cursor.moveToPosition(position);
            return cursor.getInt(0);
        }

        @Override
        public View getView(int position, View view, ViewGroup viewGroup) {
            View getview=view;
            cursor.moveToPosition(position);
            getview=getLayoutInflater().inflate(R.layout.pressure_view,null);
            TextView txtDate=(TextView)getview.findViewById(R.id.txtDate);
            txtDate.setText(cursor.getString(1));
            TextView txtHigh=(TextView)getview.findViewById(R.id.txtHigh);
            txtHigh.setText("收縮壓"+cursor.getString(2));
            TextView txtLow=(TextView)getview.findViewById(R.id.txtLow);
            txtLow.setText("舒張壓"+String.valueOf(cursor.getString(3)));
            return getview;
        }
    }
}

成果

客製化選單
https://ithelp.ithome.com.tw/upload/images/20191011/20121149AcLwaN8KbZ.png
本篇尚未實作新增資料的頁面,所以ListView資料呈現空白,下篇文章將繼續實作新增資料頁面喔~

https://ithelp.ithome.com.tw/upload/images/20191006/20121149PWP77VACaU.png

若文章有誤,歡迎大家提出建議。

/images/emoticon/emoticon31.gif

Thank you for your time.

/images/emoticon/emoticon41.gif


上一篇
[Day25]Android學習-創新挑戰-健康管理app(3)
下一篇
[Day27]Android學習-創新挑戰-健康管理app(5)
系列文
Android Studio 學習交流30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言