登录后台

页面导航

本文编写于 2402 天前,最后修改于 1667 天前,其中某些信息可能已经过时。

讲作业

先来回顾下上节课的题目「为什么 ImageView 会有背景和前景?有什么应用? 」答案让我们在实践中去体会吧。先在「drawable」里放好我们的素材:

然后设计布局

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/imageview"
    android:padding="60dp"
    android:background="@drawable/ic_backgroind"/>

其中 padding 属性控制的是控件内容与空间边缘的距离

效果如下:

还没猜到要干什么?没事,接着看,我们添加 Java 代码:

public class MainActivity extends Activity {

    int MODE = 0;
    int UNLOVE = 0;
    int LOVE = 1;
    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView)findViewById(R.id.imageview);
        imageView.setImageResource(R.drawable.ic_heart_outline);
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (MODE == UNLOVE){
                    MODE = LOVE;
                    imageView.setImageResource(R.drawable.ic_heart);
                } else {
                    MODE = UNLOVE;
                    imageView.setImageResource(R.drawable.ic_heart_outline);
                }
            }
        });
    }
}

我先是定义了三个整型的变量,其中 MODE 描述的是当前的状态,LOVE 代表实心,UNLOVE 代表空心。然后定义了一个 ImageVIew 用于保存按钮的实例。随后在 「setContentView」之后直接通过「findViewById」取得按钮的实例,然后通过设置前景来让空心显示出来。然后为这个 ImageView 绑定了一个点击监听器,在点击之后先通过 MODE 判断当前的状态,然后根据状态来切换前景图案。效果图如下:

不用我说,大家已经知道前景和背景的用处了。

对话框 AlertDialog

「AlertDialog」就是一个小框框,在窗口最顶层,能屏蔽掉其他控件的交互的 Window 。一般都是用来提示或询问重要内容的。下面的代码演示了一个最简单的对话框:

new AlertDialog.Builder(MainActivity.this)  //构造一个 Builder
        .setTitle("我是标题")                //设置标题
        .setMessage("我是正文")                //设置正文
        .create()                          //创建对话框
        .show();                          //显示对话框

也可以这么写,至于你怎么写就看你的喜好了:

AlertDialog.Builder dialog =  new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("我是标题");
dialog.setMessage("我是正文");
dialog.create().show();

先通过「AlertDialog.Builder」来创建出一个 AlertDialog 实例,这个过程需要传入当前类的实例,通常就是「类名.this」。然后调用他的各种方法来进行配置,最后调用「dialog.create().show();」来将对话框创建显示到屏幕上。效果图如下:

加入按钮

但是,,,貌似别人家的对话框有按钮呀,观察并运行如下代码:

AlertDialog.Builder dialog =  new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("我是标题");
dialog.setMessage("我是正文");
dialog.setPositiveButton("肯定按钮", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        Toast.makeText(MainActivity.this, "点击了肯定按钮", Toast.LENGTH_SHORT).show();
    }
});
dialog.setNegativeButton("否定按钮", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        Toast.makeText(MainActivity.this, "你点击了否定按钮", Toast.LENGTH_SHORT).show();
    }
});
dialog.setNeutralButton("中性按钮", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        Toast.makeText(MainActivity.this, "你点击了中性按钮", Toast.LENGTH_SHORT).show();
    }
});
dialog.create().show();

Dialog 允许我们最多添加三个按钮,根据位置来分分别是「否定按钮」,「中性按钮」,「肯定按钮」。他们的区别主要就是位置:

方法MD 位置HOLO 位置解释
setNegativeButton中间左边否定按钮
setNeutralButton最左边中间中性按钮
setPositiveButton最右边右边肯定按钮

其中「Negative」是消极的意思,「Neutral」是中性的意思,「Positive」是积极的意思,所以一般「setPositiveButton」都被定义为『确定』或『是』,「setNegativeButton」都被定义为『取消』或『否』。这三个设置按钮的方法都需要传入两个参数,第一个是按钮的文字,第二个是一个点击事件的监听器。在对话框里通常就是

new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        //点击按钮时执行的代码
    }

实现的效果:

设置不可取消

不知道你有没有发现,我们的对话框点一下空白处就会消失。但是别人家的对话框有的就没法取消呀。这时你需要:

dialog.setCancelable(false);

「Cancel」是取消的意思,这里传入「false」就是不可取消:

进度对话框

「AlertDialog」还有一个兄弟:「ProgressDialog」。「Progress」是进度的意思,字面上就翻译成「进度对话框」吧。

典型代码如下:

ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setTitle("请稍侯");
progressDialog.setMessage("正在拼命处理中....");
progressDialog.setCancelable(false);
progressDialog.show();

相信有了上面的基础,看这个已经没什么难度了:

质感设计的对话框

看了上面的截图你是不是想喷我?明明一个 Android P 的设备,对话框却是 Android 4.x 时代的样子。是呀,现在就让对话框符合质感设计:

  1. 将项目targetSdkVersion设为22或者以上
  2. 加入对应的support依赖支持 「compile 'com.android.support:appcompat-v7:22.1.0' 」
  3. 把最顶部的「import android.app.AlertDialog;」替换成「import android.support.v7.app.AlertDialog;」
  4. 修改 AndroidManifest.xml 中 Activity 的主题为 Appcompat 下的一种,如「android:theme="@style/Theme.AppCompat.Light"」
  5. 享受吧

效果如下:

这里提供一下我的 build.gradle,方便不知道在哪里添加的小白:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.example.gtf35.test"
        minSdkVersion 19
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'
    compile 'com.android.support:appcompat-v7:27.1.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

tips:「com.android.support:appcompat-v7:」后面的数字必须和「targetSdkVersion」后面的数字对应。如果不对应的话,AS 会给出修改建议,修改就好。

提供一下我的 AndroidManifest.xml ,方便不知道在哪里添加的小白:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.gtf35.test">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.Light">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

微技巧--修改按钮的文字颜色

有个前提,必须是质感设计的 Dialog,也就是必须导入了「com.android.support:appcompat」包,而且在 Java 文件顶部 import 的是「android.support.v7.app.AlertDialog」 。首先我们需要监听 dialog 的创建:

mDialog.create().setOnShowListener(new DialogInterface.OnShowListener() {
    @Override
    public void onShow(DialogInterface dialog) {
        //在对话框创建时执行的代码
    }
});
AlertDialog.Builder builder =  new AlertDialog.Builder(MainActivity.this);
builder.setTitle("提示:"); 
builder.setMessage("是否删除该文件?");
builder.setPositiveButton("确定", null);
builder.setNegativeButton("取消",null);
builder.setNeutralButton("稍后询问",null);
final AlertDialog alertDialog = builder.create();  //创建对话框,创建之后才可以监听
alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {  //绑定对话框创建监听器
    @Override
    public void onShow(DialogInterface dialog) {
        alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(Color.RED); //确定
        alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(Color.BLUE); //取消
        alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL).setTextColor(Color.BLACK); //中性
    }
});
alertDialog.show();  //显示对话框

在没有调用 show() 之前AlertDialog.getButton(DialogInterface.BUTTON_POSITIVE) 为 null。AlertDialog 的逻辑是 show()方法 中初始化了 AlertDialog 上面的控件,然后展示出来,所以在 show()方法 执行之后才能得到 button。那么我们就监听他的创建,一创建就拿到 Button 然后改颜色。由于这个过程非常快,用户感受不到。

总结

今天一不小心又写到凌晨三点,居然不觉得困,真神奇。今天我们学会了对话框的使用,还 get 到了一个小技能。今天就不留什么作业了,大家自己动手创建一个对话框练练手就好。新的一周,燥起来。

2020/5/24 注:
这是我 2018 年高中毕业的假期写的,当时并没有自己搭建博客,近期我给这一系列的文章都放到我自己的博客上。
当时写这个系列文章的想法就是扎实下基础,然后能帮到更多的人就更好了,但是大学开学之后就开始了新生活,没有大块的时间去编撰,系列文章也没有再更新过。但是我其实并不想放弃这个系列,那就,有缘再见吧,拜拜ヾ(•ω•`)o