今天來寫點跟介面有關的ʕ→ᴥ←ʔ

我們在開始學Android程式設計的時候,老師第一步大概會叫你在xml的檔案裡面拉一個TextView,然後命名HelloWorld吧

然後從此踏上了程式的不歸路(╥_╥)

 

我咧~其實寫著寫著寫到後來

就會去思考這些UI元件是怎麼來的

後來學會使用canves之後,就大致了解了

不過後來又有個疑問: 這些元件在更早之前應該都是用程式碼一點一滴地摳出來的吧

那麼他如果要在java被使用,那我又該如何設置呢?

 

後來程式中漸漸開始有很多需要靈活變化的需求後,好像有時候也需要有能在程式中寫元件的能力了

於是想著想著就寫了這篇XD

 

事不宜遲,看一下範例吧

這次沒有Github,要程式的私我我會給

來吧!

 


 

1. 咦?(゜ロ゜)

 

咦?版主你放錯了吧?

tenor

 

我並沒有搞錯範例哦(・ωー)~☆

因為範例中所有的元件都是用java完成的(包括控制)

來看一下設計檔案

 

activity_main.xml

截圖 2021-01-23 下午7.19.38

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"/>

 

見ろ!~真白だ!

不過在粉底白字的部分,我還是有給這個佈局ID

因為稍後的所有元件都是要寫在這裡面的

Okay,速速講重點吧

 


 

2. 撰寫程式

 

我的習慣一直都是直接給你範例程式抄

那麼一樣,我直接PO全部,再來講解

 

MainActivity.java

public class MainActivity extends AppCompatActivity {
    ConstraintLayout parentLayout;
    int GUIDELINE_ID = 100, SWITCH_ID = 101, TEXTVIEW_ID = 102, EDITTEXT_ID = 103, BUTTON_ID = 104;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /**令畫面中的ConstraintLayout為盛載UI們的容器*/
        parentLayout = findViewById(R.id.parent);
        initView();
        useView();

    }

    private void initView(){
        /**設置中間橫線*/
        //new一個UI
        Guideline guideline = new Guideline(this);
        //賦予此元件ID
        guideline.setId(GUIDELINE_ID);
        //設置此物件之佈局
        ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(
                ConstraintLayout.LayoutParams.WRAP_CONTENT,
                ConstraintLayout.LayoutParams.WRAP_CONTENT
        );
        lp.orientation = ConstraintLayout.LayoutParams.HORIZONTAL;
        //將佈局套入元件本身
        guideline.setLayoutParams(lp);
        //(Guideline特有)設置畫面切割佔比率
        guideline.setGuidelinePercent(0.5f);
        //將UI放進容器內
        parentLayout.addView(guideline);

        /**設置Switch Button*/
        @SuppressLint("UseSwitchCompatOrMaterialCode")
        //new一個UI
        Switch swButton = new Switch(this);
        //賦予此元件ID
        swButton.setId(SWITCH_ID);
        //設置此物件之佈局
        ConstraintLayout.LayoutParams swLayout = new ConstraintLayout.LayoutParams(
                ConstraintLayout.LayoutParams.WRAP_CONTENT
                ,ConstraintLayout.LayoutParams.WRAP_CONTENT);
        swLayout.topToTop = ConstraintLayout.LayoutParams.PARENT_ID;
        swLayout.bottomToBottom = guideline.getId();
        swLayout.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
        swLayout.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
        //將佈局套入元件本身
        swButton.setLayoutParams(swLayout);
        //(swButton特有)設置文字
        swButton.setText("放爽的");
        //將UI放進容器內
        parentLayout.addView(swButton);

        /**設置TextView*/
        TextView textView = new TextView(this);
        textView.setId(TEXTVIEW_ID);
        ConstraintLayout.LayoutParams tvLayout = new ConstraintLayout.LayoutParams(
                ConstraintLayout.LayoutParams.WRAP_CONTENT
                ,ConstraintLayout.LayoutParams.WRAP_CONTENT);
        tvLayout.topToTop = guideline.getId();
        tvLayout.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
        tvLayout.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
        textView.setLayoutParams(tvLayout);
        textView.setText("Hello!");
        textView.setTextSize(22);
        textView.setTextColor(Color.BLACK);
        parentLayout.addView(textView);

        /**設置EditText*/
        EditText editText = new EditText(this);
        editText.setId(EDITTEXT_ID);
        ConstraintLayout.LayoutParams edLayout = new ConstraintLayout.LayoutParams(
                ConstraintLayout.LayoutParams.MATCH_PARENT
                ,ConstraintLayout.LayoutParams.WRAP_CONTENT);
        edLayout.topToBottom = textView.getId();
        edLayout.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
        edLayout.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
        edLayout.topMargin = dpToPx(24);
        edLayout.rightMargin = dpToPx(32);
        edLayout.leftMargin = dpToPx(32);
        editText.setLayoutParams(edLayout);
        parentLayout.addView(editText);

        /**設置Button*/
        Button button = new Button(this);
        button.setId(BUTTON_ID);
        ConstraintLayout.LayoutParams btLayout = new ConstraintLayout.LayoutParams(
                ConstraintLayout.LayoutParams.WRAP_CONTENT
                ,ConstraintLayout.LayoutParams.WRAP_CONTENT);
        btLayout.topToBottom = editText.getId();
        btLayout.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
        btLayout.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
        btLayout.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID;
        button.setLayoutParams(btLayout);
        button.setText("確定");
        parentLayout.addView(button);

    }
    /**將DP轉為像素單位*/
    private int dpToPx(int dp) {
        return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
    }

    private void useView(){
        TextView tvShow = parentLayout.findViewById(TEXTVIEW_ID);
        EditText edInput = parentLayout.findViewById(EDITTEXT_ID);
        Button btOK = parentLayout.findViewById(BUTTON_ID);

        btOK.setOnClickListener(v->{
            String s = edInput.getText().toString();
            tvShow.setText(s);
        });
    }
}

 

好,程式抄完的出口在右上角,慢走不送(^_^)/

 

欸不對!還是看一下啦!霸偷霸偷

 

總之我們先從全域變數來看

 

ConstraintLayout parentLayout;
int GUIDELINE_ID = 100, SWITCH_ID = 101, TEXTVIEW_ID = 102, EDITTEXT_ID = 103, BUTTON_ID = 104;

 

上面的是要把UI放進去的容器

而ID的部分就是在新增元件的時候,賦予他唯一的名稱

就跟我們常用的R.id.xxxx是一樣的道理

 

再來看向onCreate

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    /**令畫面中的ConstraintLayout為盛載UI們的容器*/
    parentLayout = findViewById(R.id.parent);
    initView();
    useView();

}

 

我想了兩個副程式,initView就是初始化載入介面

也就是我們將要把UI設置寫在這裡

 

useView則是使用這些UI元件

 

OK,來看initView()吧

首先是這些內容

private void initView(){
    /**設置中間橫線*/
    //new一個UI
    Guideline guideline = new Guideline(this);
    //賦予此元件ID
    guideline.setId(GUIDELINE_ID);
    //設置此物件之佈局
    ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.WRAP_CONTENT,
            ConstraintLayout.LayoutParams.WRAP_CONTENT
    );
    lp.orientation = ConstraintLayout.LayoutParams.HORIZONTAL;
    //將佈局套入元件本身
    guideline.setLayoutParams(lp);
    //(Guideline特有)設置畫面切割佔比率
    guideline.setGuidelinePercent(0.5f);
    //將UI放進容器內
    parentLayout.addView(guideline);

    /**設置Switch Button*/
    @SuppressLint("UseSwitchCompatOrMaterialCode")
    //new一個UI
    Switch swButton = new Switch(this);
    //賦予此元件ID
    swButton.setId(SWITCH_ID);
    //設置此物件之佈局
    ConstraintLayout.LayoutParams swLayout = new ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.WRAP_CONTENT
            ,ConstraintLayout.LayoutParams.WRAP_CONTENT);
    swLayout.topToTop = ConstraintLayout.LayoutParams.PARENT_ID;
    swLayout.bottomToBottom = guideline.getId();
    swLayout.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
    swLayout.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
    //將佈局套入元件本身
    swButton.setLayoutParams(swLayout);
    //(swButton特有)設置文字
    swButton.setText("放爽的");
    //將UI放進容器內
    parentLayout.addView(swButton);

    /**設置TextView*/
    TextView textView = new TextView(this);
    textView.setId(TEXTVIEW_ID);
    ConstraintLayout.LayoutParams tvLayout = new ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.WRAP_CONTENT
            ,ConstraintLayout.LayoutParams.WRAP_CONTENT);
    tvLayout.topToTop = guideline.getId();
    tvLayout.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
    tvLayout.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
    textView.setLayoutParams(tvLayout);
    textView.setText("Hello!");
    textView.setTextSize(22);
    textView.setTextColor(Color.BLACK);
    parentLayout.addView(textView);

    /**設置EditText*/
    EditText editText = new EditText(this);
    editText.setId(EDITTEXT_ID);
    ConstraintLayout.LayoutParams edLayout = new ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.MATCH_PARENT
            ,ConstraintLayout.LayoutParams.WRAP_CONTENT);
    edLayout.topToBottom = textView.getId();
    edLayout.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
    edLayout.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
    edLayout.topMargin = dpToPx(24);
    edLayout.rightMargin = dpToPx(32);
    edLayout.leftMargin = dpToPx(32);
    editText.setLayoutParams(edLayout);
    parentLayout.addView(editText);

    /**設置Button*/
    Button button = new Button(this);
    button.setId(BUTTON_ID);
    ConstraintLayout.LayoutParams btLayout = new ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.WRAP_CONTENT
            ,ConstraintLayout.LayoutParams.WRAP_CONTENT);
    btLayout.topToBottom = editText.getId();
    btLayout.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
    btLayout.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
    btLayout.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID;
    button.setLayoutParams(btLayout);
    button.setText("確定");
    parentLayout.addView(button);

}
/**將DP轉為像素單位*/
private int dpToPx(int dp) {
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

 

嗚..吐血ヾ(´¬`)ノ

133行...我不想看了囧rz...

 

其實不會啦!我分解一下就知道其實都是一樣的東西再重複

首先我們來看其中一個元件...就拿Switch當範例吧

/**設置Switch Button*/
@SuppressLint("UseSwitchCompatOrMaterialCode")
//new一個UI
Switch swButton = new Switch(this);
//賦予此元件ID
swButton.setId(SWITCH_ID);
//設置此物件之佈局
ConstraintLayout.LayoutParams swLayout = new ConstraintLayout.LayoutParams(
        ConstraintLayout.LayoutParams.WRAP_CONTENT
        ,ConstraintLayout.LayoutParams.WRAP_CONTENT);
swLayout.topToTop = ConstraintLayout.LayoutParams.PARENT_ID;
swLayout.bottomToBottom = guideline.getId();
swLayout.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
swLayout.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
//將佈局套入元件本身
swButton.setLayoutParams(swLayout);
//(swButton特有)設置文字
swButton.setText("放爽的");
//將UI放進容器內
parentLayout.addView(swButton);

 

基本上,就是先新增一個Switch元件

再來賦予ID

然後寫他佈局需要的內容

最後在丟進主要容器中...就完成了!

 

那我們再拿另一個元件來比較一下

這邊是設置Button的部分

/**設置Button*/
Button button = new Button(this);
button.setId(BUTTON_ID);
ConstraintLayout.LayoutParams btLayout = new ConstraintLayout.LayoutParams(
        ConstraintLayout.LayoutParams.WRAP_CONTENT
        ,ConstraintLayout.LayoutParams.WRAP_CONTENT);
btLayout.topToBottom = editText.getId();
btLayout.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
btLayout.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
btLayout.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID;
button.setLayoutParams(btLayout);
button.setText("確定");
parentLayout.addView(button);

 

可以比較一下上面的程式碼,再來看看這個

或許就會看得出一咪咪咪咪咪咪的蹊蹺哦:D

 

最後是使用這些UI元件

也就是useView()的這個部分

private void useView(){
    TextView tvShow = parentLayout.findViewById(TEXTVIEW_ID);
    EditText edInput = parentLayout.findViewById(EDITTEXT_ID);
    Button btOK = parentLayout.findViewById(BUTTON_ID);

    btOK.setOnClickListener(v->{
        String s = edInput.getText().toString();
        tvShow.setText(s);
    });
}

 

這邊尤其要注意這裡

TextView tvShow = parentLayout.findViewById(TEXTVIEW_ID);
EditText edInput = parentLayout.findViewById(EDITTEXT_ID);
Button btOK = parentLayout.findViewById(BUTTON_ID);

因為這些元件是存在於最初的那個layout之中的,因此他會是parentlayout.find...

這個部分可千萬不要漏掉囉!不然他就會嘿嘿給你看XD

 


 

三下五除二就寫完了,哈哈哈哈

這篇也算比較簡單的啦(-‿◦)

不過當初我在寫的時候,也是花了我一個下午研究的

好在網路很多人提供資料,雖然零零散散的

不過最後還是靠一堆資料完成了~

那本篇文章就寫到這邊

如果覺得文章有幫助的話...↓

arrow
arrow

    碼農日常 發表在 痞客邦 留言(18) 人氣()