上一期我们讲了创建动画,我们通过创建布局文件,然后里面写animation-list表示帧动画,写rotate写旋转动画,大家有没有去试一试呢?真的是比较有趣;
好了,那么这一期我呢给大家带来了一个任何手机都有的一个功能,就是设置日期和时间,其实在安卓里面,我们可以通过时间日期对话框做到更改时间的效果:
我们就是通过对话框设置时间然后更改文本框中的内容,废话不多说,我们直接开始吧;
1、创建好布局,最好给组件都设置好id,我们后面的代码用到:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
android:gravity="center_horizontal"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置时间"
android:textSize="30sp"
android:layout_marginTop="20dp"
android:id="@+id/tv_time"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击设置时间"
android:textSize="30sp"
android:id="@+id/btn_time"
android:layout_marginTop="20dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击设置日期"
android:textSize="30sp"
android:id="@+id/btn_date"
android:layout_marginTop="20dp"/>
</LinearLayout>
这里我们就简单一点,直接使用线性布局垂直方向就可以,创建好如下布局:
这个比较简单,那么我们直接看代码;
2、创建变量,初始化,然后下按钮监听接口,在接口方法里面编写时间对话框的代码:
package com.example.mygridviewactivity;
import androidx.appcompat.app.AppCompatActivity;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.TimePicker;
import java.util.Calendar;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//1.1 新建组件变量
TextView tv_time;
Button btn_time,btn_date;
Calendar calendar;
int hour,minute,year,month,day;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.3 调用函数
init_datas();
//注册监听器
btn_time.setOnClickListener(this);
btn_date.setOnClickListener(this);
}
//1.2 初始化变量
private void init_datas(){
tv_time=findViewById(R.id.tv_time);
btn_time=findViewById(R.id.btn_time);
btn_date=findViewById(R.id.btn_date);
calendar = Calendar.getInstance();
hour = calendar.get(Calendar.HOUR);
minute = calendar.get(Calendar.MINUTE);
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DAY_OF_MONTH);
}
//1.4 实现按钮监听接口
@Override
public void onClick(View view) {
switch(view.getId()){
case R.id.btn_time:
//新建时间对话框
TimePickerDialog timePickerDialog = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int i, int i1) {
tv_time.setText("当前时间为:"+i+"时"+i1+"分");
}
},hour,minute,true);
timePickerDialog.setTitle("设置时间:");
timePickerDialog.show();
break;
case R.id.btn_date:
//新建日期对话框
DatePickerDialog datePickerDialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker datePicker, int i, int i1, int i2) {
tv_time.setText("当前日期为:"+i+"年"+(i1+1)+"月"+i2+"日");
}
},year,month,day);
datePickerDialog.setTitle("设置日期:");
datePickerDialog.show();
break;
default:
break;
}
}
}
代码不多,应该都可以看懂,所以我就不单独讲解可,给大家讲讲思路,首先我们拿到组件对象,然后实现按钮监听的接口,然后注册监听,还记得吗:
//注册监听器
btn_time.setOnClickListener(this);
btn_date.setOnClickListener(this);
一个设置时间一个设置日期;
主要代码就是这个时间对话框,怎么做的呢?其实和我们前面的进度条对话框是一个套路,只不过这个对话框的参数有点多,有5~6个,设置时间是5个,设置日期是6个,那就意味着,我们有两种对话框,一种是时间,一种是日期,但是都是一样的使用方法,所以我这里就不过多赘述,直接拿时间对话框来举例:
TimePickerDialog timePickerDialog = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int i, int i1) {
tv_time.setText("当前时间为:"+i+"时"+i1+"分");
}
},hour,minute,true);
timePickerDialog.setTitle("设置时间:");
timePickerDialog.show();
首先第一个上下文,我们设置为this,第二个是回调接口,这个接口会有提示,所以也不需要怎么记住,记住接口方法里面的i和i1就可以了,前面一个是时,后面一个是分,因为秒的话没有意义,所以就没有,再来看回调接口后面还有三个数,设置默认值的作用,hour是默认时,minute是默认秒,true表示以24小时制,我这里的hour和minute是我定义的数,获取的是当前系统的时间,是安卓系统的时间哦:
calendar = Calendar.getInstance();
hour = calendar.get(Calendar.HOUR);
minute = calendar.get(Calendar.MINUTE);
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DAY_OF_MONTH);
这个calendar是一个日历类,我们通过Calendar.getInstance()来获取,然后使用上面的方法获取响应的时间就可以了;要注意的是,我们获取到的日期的月份是当前月份的数值减一,因为系统是从0开始计算的,所以我们在设置月份的时候给它加上一既可以:
tv_time.setText("当前日期为:"+i+"年"+(i1 +1)+"月"+i2+"日");
至于日期的对话框,i1、i2、i3分别代表年月日就可以了,后面也是默认值,方法是一样的,最后不要忘了我们的对话框需要show();
GridView的运用:
在我们的手机主页是不是经常看到类似的布局,网格布局?感觉像是网格组件,O(∩_∩)O哈哈~;
其实就是我们的GridView,实现这个效果总算看起来还算高级,我们要用到大量的数据,哈希表,数列,数组,适配器,大家做好准备了吗?
1、布局,在之前的基础上加一个标题和GridView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
android:gravity="center_horizontal"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置时间"
android:textSize="30sp"
android:layout_marginTop="20dp"
android:id="@+id/tv_time"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击设置时间"
android:textSize="30sp"
android:id="@+id/btn_time"
android:layout_marginTop="20dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击设置日期"
android:textSize="30sp"
android:id="@+id/btn_date"
android:layout_marginTop="20dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="头像大全"
android:textSize="30sp"
android:layout_marginTop="20dp"
/>
<GridView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="4"
android:columnWidth="90dp"
android:verticalSpacing="10dp"
android:layout_marginTop="20dp"
android:id="@+id/gv_app"/>
</LinearLayout>
另外,大家可以看到我们每一个头像下面还有一行字,明显就是一个布局,还记得我们之前做过的spinner吗,我们同样是用的布局文件,这里我们也就复习一下吧,在layout文件夹下面新建一个文件,自定义xml文件,填入以下代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:scaleType="fitXY"
android:id="@+id/img_icon"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textSize="20sp"
android:id="@+id/tv_title"
/>
</LinearLayout>
这里布局很简单,也是线性布局,一个imageview一个标题解决,不过要注意设置好id,宽高什么的只要不是太不合理都行,我这里就设置60,当然如果为了后期好看的话可以在做后期的调整;
方向什么的保持居中就可以,垂直排;
2、那么我们马上网上下载12张偶像的头像,复制到我们的drawable文件夹下面,然后开始一系列的数据存储操作,首先定义变量:
//2.2 定义好存储数据的集合和数组
List<Map<String,Object>> items;
Map<String,Object> map;
String[] titles;
int[] icons;
String[] from;
int[] to;
SimpleAdapter simpleAdapter;
这里也都是全局变量,放在之前的变量下面就可以,我来解释一下都是装什么的,第一个items就好像是约定俗成的,跟我们最后一个适配器simpleAdapter有着不可分割的;联系:
simpleAdapter = new SimpleAdapter(this,items,R.layout.mygrid_items,from,to);
这是它的实例化代码,第一个参数是上下文,第二个是这个数列,第三个是我们刚刚写的布局文件,第四个是存的数据的键值,第五个是组建的id,也就是我们刚刚写的布局文件的组建的id,这里要注意键值需要和组件id对应起来,因为我们是通过键值来确定的资源文件和标题的;
那么是什么练习呢?就是我们第二个参数必须要一个元素是map的list,别的数列还不行,这不就像是定制的适配器吗。
回到我们定义的变量,第二个(map)不用想,就是数列里面的元素了,第三个(titles)顾名思义,标题,就是我们头像下面的文字,第四个(icons)就是我们偶像照片的id了,因为在android studio里面所有的照片都会生成一个id,是整型的所以为我们那大资源提供了很好地帮助;最后一个适配器就不用多说了吧,要注意,有适配器就会有用到适配器;
3、 那么接下来就开始填充一下数据了:
//2.3 对数据进行填充
items = new ArrayList<Map<String,Object>>();
titles = new String[]{"男1","男2","男3","男4","男5","女1","女2","女3","女4","女5","女6","女7"};
icons = new int[]{R.drawable.tou1,R.drawable.tou2,R.drawable.tou3,R.drawable.tou4,R.drawable.tou5,
R.drawable.tou6,R.drawable.tou7,R.drawable.tou8,R.drawable.tou9,R.drawable.tou10,
R.drawable.tou11,R.drawable.tou12};
//这里要注意,我们的组件和键值数组元素排列顺序必须要对应
from = new String[]{"titles","icons"};
to = new int[]{R.id.tv_title,R.id.img_icon};
for(int i = 0;i < titles.length;i++){
map = new HashMap<String,Object>();
map.put(from[0],titles[i]);
map.put(from[1],icons[i]);
items.add(map);
}
//2.4 实例化监听器
simpleAdapter = new SimpleAdapter(this,items,R.layout.mygrid_items,from,to);
这是个体力活,越多我们就要填充的越多,当然后期学会了从网上获取资源的话就没有这么麻烦了;
好,先实例化对象,泛型里面根据我们变量定义的写就可以,然后数组里面填上我们想要设置的标题和头像id,至于键值和组件数组,就要看你们的组件id定为什么了,当然这里都是定义的,我这里就简单点,就位titles和icons;
然后写一个for循环,干嘛呢?就是将我们的数据封装进我们的items,方便我们的适配器将数据读取到GridView上面显示,在循环里实例化map泛型也是一样写,然后键为titles的对应的值为titles这个数组,键为icons的对应的值为icons里面的数据,然后调用数列item的add方法将我们定义好的map添加进去;
最后,我们实例化监听器;
4、不要忘了使用哦,前面提示了:
//2.5 给我们的gridview设置监听器
gv_app.setAdapter(simpleAdapter);
这个gv_app就是我们的GridView对象,调用它的setAdapter方法就可以设置适配器,最后就会拿到那个效果了;
因为涉及到的数据存储比较多,这里我在给大家分析一下,我们定义一个数列,里面存储的是一个又一个的map,也就是键值对,这个键值就是我们看到的一张图片额和一条标题;那么如何放进去呢,我们定义两个数组和一个map,我们实例化这个map,然后将图片和标题的键值对都放进去就可以,千万不要以为我们的图片是键,文字是值,这样理解就错了,因为我们没有方法根据值拿到键,就算你可以写出来,为什么要这么麻烦?咱们直接都存储为键值对不就好了,而且这其实也是我们的适配器要求的,因为我们适配器根据的是键拿到值,我们的值的数量对应的就是我们自定义的布局文件的组件的数量,所以大家还是严格按照这个来既可以;
下面提供全部代码:
package com.example.mygridviewactivity;
import androidx.appcompat.app.AppCompatActivity;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.GridView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.TimePicker;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//1.1 新建组件变量
TextView tv_time;
Button btn_time,btn_date;
GridView gv_app;
Calendar calendar;
int hour,minute,year,month,day;
//2.2 定义好存储数据的集合和数组
List<Map<String,Object>> items;
Map<String,Object> map;
String[] titles;
int[] icons;
String[] from;
int[] to;
SimpleAdapter simpleAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.3 调用函数
init_datas();
//注册监听器
btn_time.setOnClickListener(this);
btn_date.setOnClickListener(this);
//2.5 给我们的gridview设置监听器
gv_app.setAdapter(simpleAdapter);
}
//1.2 初始化变量
private void init_datas(){
tv_time=findViewById(R.id.tv_time);
btn_time=findViewById(R.id.btn_time);
btn_date=findViewById(R.id.btn_date);
gv_app=findViewById(R.id.gv_app);
calendar = Calendar.getInstance();
hour = calendar.get(Calendar.HOUR);
minute = calendar.get(Calendar.MINUTE);
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DAY_OF_MONTH);
//2.3 对数据进行填充
items = new ArrayList<Map<String,Object>>();
titles = new String[]{"男1","男2","男3","男4","男5","女1","女2","女3","女4","女5","女6","女7"};
icons = new int[]{R.drawable.tou1,R.drawable.tou2,R.drawable.tou3,R.drawable.tou4,R.drawable.tou5,
R.drawable.tou6,R.drawable.tou7,R.drawable.tou8,R.drawable.tou9,R.drawable.tou10,
R.drawable.tou11,R.drawable.tou12};
//这里要注意,我们的组件和键值数组元素排列顺序必须要对应
from = new String[]{"titles","icons"};
to = new int[]{R.id.tv_title,R.id.img_icon};
for(int i = 0;i < titles.length;i++){
map = new HashMap<String,Object>();
map.put(from[0],titles[i]);
map.put(from[1],icons[i]);
items.add(map);
}
//2.4 实例化监听器
simpleAdapter = new SimpleAdapter(this,items,R.layout.mygrid_items,from,to);
}
//1.4 实现按钮监听接口
@Override
public void onClick(View view) {
switch(view.getId()){
case R.id.btn_time:
//新建时间对话框
TimePickerDialog timePickerDialog = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int i, int i1) {
tv_time.setText("当前时间为:"+i+"时"+i1+"分");
}
},hour,minute,true);
timePickerDialog.setTitle("设置时间:");
timePickerDialog.show();
break;
case R.id.btn_date:
//新建日期对话框
DatePickerDialog datePickerDialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker datePicker, int i, int i1, int i2) {
tv_time.setText("当前日期为:"+i+"年"+(i1 +1)+"月"+i2+"日");
}
},year,month,day);
datePickerDialog.setTitle("设置日期:");
datePickerDialog.show();
break;
default:
break;
}
}
}
好了,那么这一期就到这,比较长,但是内容还是比较简单,快去试试吧;
对了,点个赞再走呗,一万多个字太累了。。。