iT邦幫忙

2023 iThome 鐵人賽

DAY 18
0

前言

Intent可以做到將現在的Activity跳到另外一個Activity的效果,比方說我可以製作一個登入介面,登入後就會跳到App的主畫面;又或者按下一個按鈕就跳到搜尋天氣資訊的介面......。

成果展示

布局設定

首先附上這次的GitHub
本次實作會製作三個介面:

  1. 登入的介面
  2. 註冊的介面
  3. 主畫面的介面

登入介面是App開啟時最先看到的介面,接著因為沒有註冊就不能登入所以也設計了一個註冊的介面,會用Dialo來顯示,註冊完就可以用帳號密碼登入,最後就會用Intent跳轉到MainActivity。

可以從專案名稱按右鍵 > New > Activity > Empty Views Activity
這樣可以建立一個乾淨的Activity並且同時建立一個布局檔,可以省一點步驟
https://ithelp.ithome.com.tw/upload/images/20230928/20161500LWI8vTMsSg.png
接著為你的Activity命名,他會同時幫你把layout也命名,最後按下finish就成功建立囉~
https://ithelp.ithome.com.tw/upload/images/20230928/20161500TSuGgKSLtF.png

  • 登入介面

https://ithelp.ithome.com.tw/upload/images/20230928/20161500nhy7QHgWK9.png
由於這次的設定跟程式碼都偏長,布局的部分我就都以圖文解說為主,程式的部分再將重點部分貼上來解說。

首先登入介面,這次我設計了一個可以輸入帳密的兩個EditText;放了兩張跟帳號密碼有關的圖在旁邊,這部分我使用TextView放置圖片,用到了background將複製進drawable的圖片給引入;接著放了一個煞有其事的圖片在上面,這部分我使用到了ImageView這個物件,使用方法很簡單,一放出來之後就會跳出這個畫面https://ithelp.ithome.com.tw/upload/images/20230928/20161500HEZH3FcSHa.png
將想放入的圖片事先加進Drawable,就可以在畫面左下那個清單內找到,選取後在按下右下方的Ok就成功將圖片放進介面內囉~除此之外也可以使用android studio內建的圖片;接著放了註冊按鈕以及登入按鈕,本次的設計中會用一種很偷懶的方式存取帳號跟密碼,這部分就到了程式的部分再細說。

  • 註冊介面

https://ithelp.ithome.com.tw/upload/images/20230928/20161500vHpblfeIXP.png
這裡我添加了兩個EditText來輸入要註冊的帳號密碼,按下建立後會將輸入的帳號跟密碼存入陣列中,並且關閉Dialog,按下取消就是直接關閉Dialog。

  • 主畫面

https://ithelp.ithome.com.tw/upload/images/20230928/20161500Smxa3dJehK.png
這次的主角不是主畫面,所以這裡我就做得比較隨便了,隨便弄一個TextView讓人看得出有換Activity而已。

程式碼

這次的實作除了會寫Login的Activity以外,還會新建一個class,用來創立一個ArrayList來簡單的做到動態新增帳號密碼的功能,要注意的是,本次實作使用的方式,每次開啟App時都會將陣列給清空,因此如果只是當下會用到的話倒是是可以考慮這種存取方式,但如果是想存取像帳號密碼這種需要一直存在的資料的話,最好還是結合內建的資料庫系統來存取會比較好,例如:SharedPreferences、Room、SQLite。

  • AccountPasswordData

首先建立一個class命名為AccountPasswordData

import java.util.ArrayList;
import java.util.HashMap;

public class AccountPasswordData {
    private ArrayList<HashMap<String,String>> data = new ArrayList<>();
    public void setActPwdData(String account,String password){
        HashMap hashMap = new HashMap();
        hashMap.put("Account",account);
        hashMap.put("Password",password);
        this.data.add(hashMap);
    }

    public ArrayList<HashMap<String,String>> getActPwdData(){
        return data;
    }
}

可以看到我在第一行先創立了一個ArrayList,並且規定裡面的資料要以HashMap的形式存取

public void setActPwdData(String account,String password){
        HashMap hashMap = new HashMap();
        hashMap.put("Account",account);
        hashMap.put("Password",password);
        this.data.add(hashMap);
    }

接著撰寫了一個方法setActPwdData用來存取帳號跟密碼,呼叫這個方法時還要傳入帳號跟密碼,接著可以看到我建立了一個hashMap,然後就將接收到的帳號跟密碼傳入,最後再把輸入完資料的hashMap丟給我的ArrayList

public ArrayList<HashMap<String,String>> getActPwdData(){
        return data;
    }

最後看到getActPwdData這裡,我將個方法設計成呼叫後會傳回data。

  • LoginActivity
    private EditText account,password;
    private Button register,login;
    private Dialog dialog;
    private AccountPasswordData accountPasswordData;

將該宣告的物件都宣告,因為會使用到Dialog以及AccountPasswordData,所以這裡也要進行宣告

    account = findViewById(R.id.account);
    password = findViewById(R.id.password);
    register = findViewById(R.id.register_button);
    login = findViewById(R.id.login_button);

    dialog = new Dialog(this);
    dialog.setContentView(R.layout.register_dialog);
    accountPasswordData = new AccountPasswordData();

    register.setOnClickListener(view -> setDialog());
    login.setOnClickListener(view -> checkActPwdData(account.getText().toString(),password.getText().toString()));

Dialog的部分一樣先初始化並綁定頁面,accountPasswordData也是進行初始化的動作,接著就是兩個按鈕的點擊事件,註冊按鈕按下後會呼叫設定Dialog的方法,登入按鈕則是呼叫檢查帳密的方法並把輸入的帳密也傳進去。

setDialog

    private void setDialog() {
        dialog.show();
        EditText register_act = dialog.findViewById(R.id.register_act);
        EditText register_pwd = dialog.findViewById(R.id.register_pwd);
        Button cancel = dialog.findViewById(R.id.cancel);
        Button create = dialog.findViewById(R.id.create);

        cancel.setOnClickListener(view -> {
            register_act.setText("");
            register_pwd.setText("");
            dialog.dismiss();
        });
        create.setOnClickListener(view -> {
            accountPasswordData.setActPwdData(register_act.getText().toString(),register_pwd.getText().toString());
            register_act.setText("");
            register_pwd.setText("");
            dialog.dismiss();
        });
    }

我設計先將Dialog給顯示出來,再來綁定了在Dialog上的物件id,然後就可以設計個別的點擊事件

        cancel.setOnClickListener(view -> {
            register_act.setText("");
            register_pwd.setText("");
            dialog.dismiss();
        });

取消按鈕按下後,將兩個EditText清空,接著就把Dialog給關掉

        create.setOnClickListener(view -> {
            accountPasswordData.setActPwdData(register_act.getText().toString(),register_pwd.getText().toString());
            register_act.setText("");
            register_pwd.setText("");
            dialog.dismiss();
        });

建立按鈕按下後,呼叫AccountPasswordData的setActPwdData,並把要註冊的帳號跟密碼丟進去,到這裡就成功新增了一組帳密,接著一樣地將EditText清空,然後關閉Dialog。

checkActPwdData

    private void checkActPwdData(String act, String pwd) {
        ArrayList<HashMap<String,String>> data = accountPasswordData.getActPwdData();
        for (int i = 0; i < data.size(); i++) {
            if (data.get(i).get("Account").equals(act) && data.get(i).get("Password").equals(pwd)){
                Intent intent = new Intent();
                intent.setClass(this, MainActivity.class);
                startActivity(intent);
            }
            else{
                password.setText("");
                Log.d("test", "登入失敗");
            }
        }
    }

首先我建立了一個ArrayList去跟AccountPasswordData要取存放帳密資料的陣列,接著用for迴圈去一組一組的對取傳進來到帳號跟密碼,再來成功的話就會執行跳轉頁面的指令

        Intent intent = new Intent();
        intent.setClass(this, MainActivity.class);
        startActivity(intent);

使用Intent就可以執行跳轉的功能,首先建立一個Intent,接著用setClass指定( 呼叫指令的頁面 , 目標頁面 ),最後就是執行命令startActivity,並將要執行的intent放進去,就可以順利跳轉頁面囉~

  • 補充:

如果想要將一些資料給一起帶到下個Activity的話,可以使用putExtra、putExtras這兩個指令,使用的方法都是先輸入Key,然後輸入要傳入的Value,兩個的差別在於前者可以放入各式個樣的資料,但傳入大量的資料就沒那麼方便,後者則是可以傳入Bundle,利用Bundle可以像裡面存入資料的方式(Key跟Value),將大量的資料一次帶到下個Activity接收,接收資料的方式:

        Intent intent = getIntent();

        if (intent != null){
            String data = intent.getStringExtra("Key");
            String[] dataList = intent.getStringArrayExtra("Key");
            ArrayList<HashMap<String,String>> arrayList = (ArrayList<HashMap<String, String>>) intent.getSerializableExtra("Key");
        }

第一行接收了傳入的資料,接著可以使用if判斷式判斷intent是否為null,再決定要不要做接收資料的動作

  • String data = intent.getStringExtra("Key");,當傳入的資料為String可以使用getStringExtra來接收。
  • intent.getStringArrayExtra("Key");,當傳入的資料為List型態時可以使用,使用Bundle傳入資料的話,接收的部分也是這樣寫。
  • intent.getSerializableExtra("Key");,這個指令會使用在傳入的資料較複雜時,比如可能我往你面傳入ArrayList<HashMap<String,String>>的型態的資料的話,就必須要像範例中的那樣打,同樣的如果我傳入的是從其他class寫的資料,我也必須要用個方法接收。

以上就是本次的Intent,結合了登入介面希望透過這種簡單得實作,可以讓讀者更加清楚使用的方法,下一篇會介紹怎麼將Intent結合RecyclerView,在點擊RecyclerView的項目時可以直接跳到跟該項目有關的頁面。


上一篇
【DAY 17】 抓取天氣API,做一個自己的天氣APP!(下)
下一篇
【DAY 19】 RecyclerView結合Intent
系列文
Android Studio開發過程和介紹30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言