【Android】10.0 UI开发(一)——如何编写程序界面、常见控件的使用

1.0 通过代码来记录控件,大抵有以下几个控件
  • TextView 文本显示
  • Button 按钮
  • EditText 文本输入
  • ImageView 插入图片
  • AlertDialog 在当前界面弹出一个对话框,置于所有页面元素之上,能够屏蔽掉其他空间的交互能力。因此一般用于提示一些非常重要的内容或者警告信息。比如防止用户误删重要内容,在删除前弹出一个确认对话框。
  • ProgressBar 圆圈进度条
2.0 新建一个项目,取名随意,我的叫ViewControl。

项目目录如下:

image
3.0 这里需要在res新建一个文件夹,程序所需的图片放在“drawable”文件夹,但是这个目录并没有指定具体的分辨率,我们新建一个名称为“drawable-xhdpi”的文件夹,把准备好的两张照片放进去,注意文件名称不能有空格号,我这个两张图片随便找的,目前选的都是200px*200px大小的图片。
4.0 先看activity_main.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!--android中所有控件都具有android:layout_width和android:layout_height这两个属性-->
    <!--可选值有三种,match_parent、wrap_content、fill_parent-->
    <!--match_parent == fill_parent,但fill_parent不推荐使用-->
    <!--match_parent:表示控件大小和父类布局的大小一样-->
    <!--wrap_content:当前控件大小刚好包含朱里面的内容-->
    <!--android:gravity:文字的对齐方式,可选值有top、bottom、left,right、center等,可以用“|”符号同时指定多个值-->
    <!--选择center表左右和上下都中间对齐,等同于center_vertical|center_horizontal-->
    <!--android:textSize:文字大小,android中用sp这个单位-->
    <!--android:textColor文字颜色-->
    
    <TextView
        android:id="@+id/text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="这是一个文本控件"
        android:textColor="#00ff00"
        android:textSize="24sp"
        app:layout_constraintTop_toTopOf="parent" />
    
    <!--android:textAllCaps:是否使用所有英文字母自动进行大写转换功能-->
    <Button
        android:id="@+id/button_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="退出程序"
        android:textAllCaps="false"
        app:layout_constraintBottom_toBottomOf="parent" />
    
    <!--&lt;!&ndash;EditText:用户输入和编辑内容,并可以在程序中对这些内容进行处理。&ndash;&gt;-->
    <!--&lt;!&ndash;应用场景:发短信、发微博、聊QQ等&ndash;&gt;-->
    <!--&lt;!&ndash;android:maxLines:指定EditText最大行数&ndash;&gt;-->
    <!--android:hint:很轻松就实现输入框提示,在输入后就会消失。-->
    <EditText
        android:id="@+id/edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请在这里随便敲字,反正不管"
        android:maxLines="2"
        app:layout_constraintTop_toBottomOf="@+id/text_view" />

    <Button
        android:id="@+id/button_1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="点击记录"
        android:textAllCaps="false"
        app:layout_constraintTop_toBottomOf="@+id/edit_text" />

    <!--插入图片-->
    <ImageView
        android:id="@+id/image_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/logo200px"
        app:layout_constraintTop_toBottomOf="@+id/button_1" />

    <Button
        android:id="@+id/button_3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="切换图片"
        android:textAllCaps="false"
        app:layout_constraintTop_toBottomOf="@+id/image_view" />

    //显示一个进度条
    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/button_3"
        />

    <Button
        android:id="@+id/button_4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="隐藏/显示进度条"
        android:textAllCaps="false"
        app:layout_constraintTop_toBottomOf="@+id/progress_bar" />

</android.support.constraint.ConstraintLayout>

4.1 首先看文件头,<android.support.constraint.ConstraintLayout>标签,ConstraintLayout是Android Studio 2.2中主要的新增功能之一,所以自动生成的布局文件不再用以前的布局标签。ConstraintLayout翻译为 约束布局,也有人把它称作 增强型的相对布局,由 2016 年 Google I/O 推出。扁平式的布局方式,无任何嵌套,减少布局的层级,优化渲染性能。从支持力度而言,将成为主流布局样式,完全代替其他布局。集万千宠爱于一身的小公举,完全兼容约束集 LinearLayout(线性布局)和RelativeLayout(相对布局)。

4.2 因为目前我参考的学习资料时郭霖先生的《第一行代码——Android 第二版》,大家可以参考下郭霖先生的博文:

Android新特性介绍,ConstraintLayout完全解析

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/53122387

但在写这些代码的时候,我看的是另一篇博文,比起郭霖大神的显得很晦涩难懂,但还是硬着头皮学会了,而且其实这样去学会,再回头看郭霖大神的博文,反而能够很快从应用层面到代码层面都可以快速理解,主要是新的布局使编程变得更加容易便捷了。

Android ConstraintLayout 使用详解

//www.greatytc.com/p/b884b8c46584

基于此,该标签就不详细记录了。

4.3 控件标签的说明在代码里面了。总之呢,效果就是这样了:

image
5.0 这里我新建了两个java类,注意,不是活动,是普通的java类,在com.example.viewcontrol目录上右击,new→Java Class,输入类名ActivityCollector,完成。再同样的方法建立BaseActivity类:
image
image
6.0 这里我们先解释下BaseActivity类,BaseActivity.java:
package com.example.viewcontrol;


import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

public class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("BaseActivity", getClass().getSimpleName());
        ActivityCollector.addActivity(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }
}

这个类的作用主要是能够方便开发人员随时知道自己目前项目运行时,哪一个活动位于栈顶,这里需要注意的是,别导错包,别导错包,别导错包,重要的话说三遍。

至于其中:

ActivityCollector.addActivity(this);

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }

是结合ActivityCollector类,在用户创建活动时调用该类的addActivity()方法,在销毁活动时,调用removeActivity()方法。

7.0 类主要作用是实时掌控所有的活动,并在需要时,可以杀死所有的活动,一次性销毁,而不需要按Back键很多次直到返回栈清空。ActivityCollector.java:
package com.example.viewcontrol;

import android.app.Activity;

import java.util.ArrayList;
import java.util.List;

public class ActivityCollector {
    public static List<Activity> activities = new ArrayList<>();

    //添加活动
    public static void addActivity(Activity activity){
        activities.add(activity);
    }

    //移除活动
    public static void removeActivity(Activity activity){
        activities.remove(activity);
    }

    //销毁所有活动
    public static void finishAll(){
        for (Activity activity:activities){
            if (!activity.isFinishing()){
                activity.finish();

            }
        }
    }
}

可以看到,里面都设置成为静态方法,并利用数组作为模拟的返回栈存储活动,我们可以直接调用类名点方法名直接调用,而不需要去创建实例。

8.0 这里是大头,MainActivity.java
package com.example.viewcontrol;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;

public class MainActivity extends BaseActivity {
    private EditText editText;
    private ImageView imageView;
    private ProgressBar progressBar;
    private int a = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button1 = (Button) findViewById(R.id.button_1);
        //存储输入的内容
        editText = (EditText) findViewById(R.id.edit_text);
        imageView = (ImageView) findViewById(R.id.image_view);
        progressBar = (ProgressBar) findViewById(R.id.progress_bar);
        //获取输入的内容
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //提示打印
                String inputText = editText.getText().toString();
                Toast.makeText(MainActivity.this, inputText, Toast.LENGTH_SHORT).show();
            }
        });

//        点击退出程序,交互性提示
        Button button2 = (Button) findViewById(R.id.button_2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //创建AlertDialog实例
                AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
//                设置标题
                dialog.setTitle("提示");
//                设置内容
                dialog.setMessage("确定退出APP?");
//                是否可以用Back键关闭对话框
                dialog.setCancelable(false);
//                设置确认按钮的点击事件
                dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCollector.finishAll();
//                      杀掉当前进程代码,killProcess()方法
                        android.os.Process.killProcess(android.os.Process.myPid());
                    }
                });
//                设置取消按钮的点击事件
                dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                });
                //配置好后用show()方法将电话框显示出来
                dialog.show();


            }
        });

//        点击切换图片
        Button button3 = (Button) findViewById(R.id.button_3);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (a == 1) {
                    imageView.setImageResource(R.drawable.qq2);
                    a = 0;
                } else {
                    imageView.setImageResource(R.drawable.logo200px);
                    a = 1;
                }

            }
        });

        //隐藏/显示进度条
        Button button4 = (Button) findViewById(R.id.button_4);
        button4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                这里在书上案例还用了用的ProgressDialog类,但在api-28时,提示,这个方法自api-26起被弃用
//                如果想模仿ProgressDialog出现时,用户无法与界面继续交互的效果,百度
                if (progressBar.getVisibility() == View.GONE) {
                    progressBar.setVisibility(View.VISIBLE);
                } else {
                    progressBar.setVisibility(View.GONE);
                }
            }
        });
    }
}

8.1 首先代码中创建了四个私有变量,说明这四个变量只需要在这个类中使用即可。

 private EditText editText; //EditText  输入框实例
 private ImageView imageView; //图片实例
 private ProgressBar progressBar; //交互提示
 private int a = 1;  //一个简单的计数器,用于图片切换时使用的变量。

8.2 下列类似的内容都是为了绑定布局文件中的控件,也不多说。

Button button1 = (Button) findViewById(R.id.button_1);
//存储输入的内容
editText = (EditText) findViewById(R.id.edit_text);
imageView = (ImageView) findViewById(R.id.image_view);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);

8.3 我们看对内容为“点击记录”按钮进行监控的代码:

button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //提示打印
                String inputText = editText.getText().toString();
                Toast.makeText(MainActivity.this, inputText, Toast.LENGTH_SHORT).show();
            }
        });

editText实例存储了输入框输入的内容,相当于临时数据的保存,我们可以及时操作临时数据,以免丢失。
通过调用getText()和toString()方法,将输入框的内容保存,并用Toast提示打印出来(当然,你也可以进行其他操作,比如保存)
实现效果:


image
image

8.4 我们看对内容为“退出程序”按钮进行监控的代码,这个按钮在屏幕的左下角:

//        点击退出程序,交互性提示
        Button button2 = (Button) findViewById(R.id.button_2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //创建AlertDialog实例
                AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
//                设置标题
                dialog.setTitle("提示");
//                设置内容
                dialog.setMessage("确定退出APP?");
//                是否可以用Back键关闭对话框
                dialog.setCancelable(false);
//                设置确认按钮的点击事件
                dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCollector.finishAll();
//                      杀掉当前进程代码,killProcess()方法
                        android.os.Process.killProcess(android.os.Process.myPid());
                    }
                });
//                设置取消按钮的点击事件
                dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                });
                //配置好后用show()方法将电话框显示出来
                dialog.show();


            }
        });
image
image

除了上图讲述以外,在“确定”选项还有操作代码:

 dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCollector.finishAll();
//                      杀掉当前进程代码,killProcess()方法
                        android.os.Process.killProcess(android.os.Process.myPid());
                    }
                });

这里第一句调用ActivityCollector类里面的finishAll()方法,杀掉所有的活动 == 返回栈清空。

第二句看着用吧,详细解释我也不知道,但是——这个killProcess()方法只能用于杀掉当前程序的进程。这样两句代码彻底将该应用程序锁占用的所有资源全部释放出来,做个好人哦不,做个好APP。

8.5 接着看对内容为“切换图片”按钮进行监控的代码,这个按钮在图片的下面:

//        点击切换图片
        Button button3 = (Button) findViewById(R.id.button_3);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (a == 1) {
                    imageView.setImageResource(R.drawable.qq2);
                    a = 0;
                } else {
                    imageView.setImageResource(R.drawable.logo200px);
                    a = 1;
                }

            }
        });

这里用变量a做一个简单的图片切换效果而已

这里调用imageView类的setImageResource()方法,来修改图片控件里的图片

8.6 接着看对内容为“隐藏/显示进度条”按钮进行监控的代码,这个按钮在图片的下面:

 //隐藏/显示进度条
        Button button4 = (Button) findViewById(R.id.button_4);
        button4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                这里在书上案例还用了用的ProgressDialog类,但在api-28时,提示,这个方法自api-26起被弃用
//                如果想模仿ProgressDialog出现时,用户无法与界面继续交互的效果,百度
                if (progressBar.getVisibility() == View.GONE) {
                    progressBar.setVisibility(View.VISIBLE);
                } else {
                    progressBar.setVisibility(View.GONE);
                }
            }
        });

在郭霖先生的《第一行代码——Android 第二版》书中除了上面锁控制的转圈的进度条,还有一个ProgressDialog进度条,他的功能时除了弹出圈圈之外,还位于所有页面元素顶端,封死其他页面操作。但不推荐用,我也不去实现它了。至于取代方案,没有去研究学习,暂且放下。

8.7 在8.6的代码中,getVisibility()方法用于判断ProgressBar是否可见,如果可见,就设置为不可见状态,如果不可见,就设置为可见状态。运行状况如下:

image
image
9.0 在郭霖先生的《第一行代码——Android 第二版》书中接下来的内容主要讲布局,但是因为使用ConstraintLayout标签,导致大量内容处于弃用(无效)状态。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,110评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,443评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,474评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,881评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,902评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,698评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,418评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,332评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,796评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,968评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,110评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,792评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,455评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,003评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,130评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,348评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,047评论 2 355