手记

【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 使用详解

https://www.jianshu.com/p/b884b8c46584

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

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

image

5.0 这里我新建了两个java类,注意,不是活动,是普通的java类,在com.example.viewcontrol目录上右击,newJava 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是否可见,如果可见,就设置为不可见状态,如果不可见,就设置为可见状态。运行状况如下:



作者:我睡醒刚刚
链接:https://www.jianshu.com/p/20a7d83512b6


0人推荐
随时随地看视频
慕课网APP