第一行代码-第二版(郭霖著)笔记三(UI控件)
目录
一、常用控件的使用方法
1.TextView
2.Button
3.EditText
4.ImageView
5.ProgressBar
6.AlertDialog
7.ProgressDialog
二、四种基本布局
1.线性布局
2.相对布局
3.帧布局
4.百分比布局
三、创建自定义控件
1.引入布局
问题:给控件设置背景后,背景不生效
2.创建自定义控件
四、最常用和最难用的控件---ListView
1.ListView的简单用法
2.定制LsitView的界面
3.提升ListView的运行效率
4.ListView的点击事件
五、更强大的滚动控件---RecyclerView
1.RecyclerView的基本用法
问题:添加库的依赖时怎么确定最新的版本号是多少
2.实现横向滚动和瀑布流布局
3.RecyclerView的点击事件
一、常用控件的使用方法
1.TextView
android:gravity="center" 可选值:top、bottom、left、right、center等,可以用"|"来同时指定多个值,center表示文字在垂直和水平方向都居中
android:textSize 指定文字的大小,单位为sp
android:textColor 指定文字的颜色
<TextViewandroid:id="@+id/textView"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="This is TextView"
/>
可选值有3种:match_parent、wrap_content和固定值。固定值表示表示给控件指定一个固定的尺寸,单位一般用dp,这是一种屏幕密度无关的尺寸单 位,可以保证在不同分辨率的手机上显示效果尽可能地一致,如50 dp就是一个有效的固定值。
2.Button
android:textAllCaps="false" 禁用英文字母自动进行大写转换
3.EditText
android:hint="提示性文本" 指定一段提示性文本
android:maxLines="2" 指定EditText最大行数为2行
EditText的getText()方法可以获取到输入的内容,再调用toString()方法转换成字符串
4.ImageView
ImageView的setImageResource()方法可以更改图片
5.ProgressBar
所有Android控件都具有可见属性,通过android:visibility指定,可选值:visible,invisible,gone
代码设置控件的可见性:setVisibility(),可以传入View.VISIBLE,View.INVISIBLE,View.GONE
水平进度条设置:style="?android:attr/progressBarStyleHorizontal"
给进度条设置最大值:android:max="100"
动态更改进度条的进度:getProgress()和setProgress()
6.AlertDialog
public void onClick(View v) {switch(v.getId()){case R.id.button://通过AlertDialog.Builder来获取AlertDialog的实例AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);dialog.setTitle("对话框的题目");dialog.setMessage("对话框的信息");dialog.setCancelable(true);dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {}});dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {}});dialog.show();break;default:break;}
}
7.ProgressDialog
public void onClick(View v) {switch(v.getId()){case R.id.button:ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);progressDialog.setTitle("这是一个进度对话框");progressDialog.setMessage("正在加载中...");progressDialog.setCancelable(true);progressDialog.show();break;default:break;}
}
二、四种基本布局
1.线性布局
android:orientation属性指定控件的排列方向,垂直排列是vertical,水平排列是horizontal
android:layout_gravity 指定控件在布局中的对齐方式
android:layout_weight 使用比例的方式来指定控件的大小
dp是Android用于指定控件大小和间距等属性的单位
2.相对布局
控件相对于父布局进行定位:
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
控件相对于控件进行定位:
android:layout_above="@id/button_2"
android:layout_toLeftOf="@id/button_2"
android:layout_below="@id/button_2"
3.帧布局
所有控件默认摆放在布局的左上角,可以使用layout_gravity属性来指定控件在布局中的对齐方式
4.百分比布局
添加百分比布局依赖:implementation 'androidx.percentlayout:percentlayout:1.0.0'
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
三、创建自定义控件
1.引入布局
引入布局可以减少代码重复
引入布局的代码:<include layout="@layout/title"/>
如何隐藏系统自带的标题栏:getSupportActionBar()方法获得ActionBar的实例,再通过实例调用hide()方法即可
问题:给控件设置background(背景)后,背景不生效
解决:
找到项目中的这两个xml文件,将parent="Theme.MaterialComponents.DayNight.DarkActionBar"修改为parent="Theme.MaterialComponents.DayNight.NoActionBar.Bridge" 即可解决
2.创建自定义控件
引入的布局中的一些控件要求能够响应事件,如果在每个活动都注册响应事件,就会增加重复代码,创建自定义控件可以解决该问题。
步骤:新建一个类继承LinearLayout(这个类就成了自定义控件),在类中注册点击事件,然后在布局文件中添加这个自定义控件
public class TitleLayout extends LinearLayout {public TitleLayout(Context context, @Nullable AttributeSet attrs) {super(context, attrs);//LayoutInflater可以对布局文件进行动态加载。//第一个参数是布局文件的id,第二个参数是给加载好的布局再添加一个父布局LayoutInflater.from(context).inflate(R.layout.title,this);Button titleBack = findViewById(R.id.title_back);Button titleEdit = findViewById(R.id.title_edit);titleBack.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {((Activity)getContext()).finish();}});titleEdit.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(getContext(),"你点击了EDIT",Toast.LENGTH_SHORT).show();}});}
}
现在自定义控件已经创建好了,然后我们需要在布局文件中添加这个自定义控件,修改activity_main.xml中的代码,如下所示:
四、最常用和最难用的控件---ListView
1.ListView的简单用法
<ListViewandroid:id="@+id/list_view"android:layout_width="match_parent"android:layout_height="match_parent"/>
public class MainActivity extends AppCompatActivity {private String[] data ={"Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango","Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango"};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//适配器构造函数中依次传入当前上下文、ListView子项的布局id,以及要适配的数据ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, data);ListView listView = findViewById(R.id.list_view);listView.setAdapter(adapter);}
}
2.定制LsitView的界面
主要思想:为ListView的子项指定一个我们自定义的布局,用于设置每个item的样式;还要创建一个自定义的适配器,用于把数据传递给ListView
<?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"><ImageViewandroid:id="@+id/fruit_image"android:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewandroid:id="@+id/fruit_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_gravity="center_vertical"/></LinearLayout>
public class FruitAdapter extends ArrayAdapter {private int resourceId;public FruitAdapter(@NonNull Context context, int resource, @NonNull List objects) {super(context, resource, objects);resourceId = resource;}@NonNull@Overridepublic View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {Fruit fruit = (Fruit) getItem(position);View view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);TextView fruitName = view.findViewById(R.id.fruit_name);ImageView fruitImage = view.findViewById(R.id.fruit_image);fruitName.setText(fruit.getFruitName());fruitImage.setImageResource(fruit.getImageId());return view;}
}
3.提升ListView的运行效率
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {Fruit fruit = (Fruit) getItem(position);View view;ViewHolder viewHolder;//convertView参数用于将之前加载好的布局进行缓存if(convertView==null){view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);viewHolder = new ViewHolder();viewHolder.fruitName = view.findViewById(R.id.fruit_name);viewHolder.fruitImage = view.findViewById(R.id.fruit_image);//将ViewHolder存储在View中view.setTag(viewHolder);}else{view = convertView;//重新获取ViewHolderviewHolder = (ViewHolder) view.getTag();}viewHolder.fruitName.setText(fruit.getFruitName());viewHolder.fruitImage.setImageResource(fruit.getImageId());return view;
}class ViewHolder{ImageView fruitImage;TextView fruitName;
}
4.ListView的点击事件
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {Fruit fruit = (Fruit) fruitList.get(position);Toast.makeText(MainActivity.this, fruit.getFruitName(), Toast.LENGTH_SHORT).show();}
});
五、更强大的滚动控件---RecyclerView
1.RecyclerView的基本用法
导入依赖:
implementation 'androidx.recyclerview:recyclerview:1.1.0'
问题:添加库的依赖时怎么确定最新的版本号是多少
鼠标放到对应的库代码处,当有更新的库版本时,Android Studio会主动提醒你,并告诉你最新的版本号是多少
修改activity_main.xml中的代码:
<androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recycler_view"android:layout_width="match_parent"android:layout_height="match_parent"/>
Fruit类和fruit_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/fruit_image"android:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewandroid:id="@+id/fruit_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_gravity="center_vertical"/></LinearLayout>
为RecyclerView准备一个适配器
public class FruitAdapter2 extends RecyclerView.Adapter<FruitAdapter2.ViewHolder> {List<Fruit> fruitList;//这里的static不写发现也不报错,但是还是要写static class ViewHolder extends RecyclerView.ViewHolder {ImageView fruitImage;TextView fruitName;public ViewHolder(@NonNull View itemView) {super(itemView);fruitImage = itemView.findViewById(R.id.fruit_image);fruitName = itemView.findViewById(R.id.fruit_name);}}@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);ViewHolder holder = new ViewHolder(view);return holder;}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {Fruit fruit = fruitList.get(position);holder.fruitName.setText(fruit.getFruitName());holder.fruitImage.setImageResource(fruit.getFruitImage());}@Overridepublic int getItemCount() {return fruitList.size();}
}
修改MianActivity中的代码:
public class MainActivity extends AppCompatActivity {private List fruitList = new ArrayList<Fruit>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initFruits();RecyclerView recyclerView = findViewById(R.id.recycler_view);FruitAdapter adapter = new FruitAdapter(fruitList);//指定RecyclerView的布局方式,此处是线性布局LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);recyclerView.setLayoutManager(linearLayoutManager);recyclerView.setAdapter(adapter);}private void initFruits(){for (int i = 0; i < 2; i++) {Fruit apple = new Fruit("Apple", R.drawable.apple_pic);fruitList.add(apple);Fruit banana = new Fruit("Banana", R.drawable.banana_pic);fruitList.add(banana);Fruit orange = new Fruit("Orange", R.drawable.orange_pic);fruitList.add(orange);Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);fruitList.add(watermelon);Fruit pear = new Fruit("Pear", R.drawable.pear_pic);fruitList.add(pear);Fruit grape = new Fruit("Grape", R.drawable.grape_pic);fruitList.add(grape);Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);fruitList.add(pineapple);Fruit strawberry = new Fruit("Strawberry", R.drawable.strawberry_pic);fruitList.add(strawberry);Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);fruitList.add(cherry);Fruit mango = new Fruit("Mango", R.drawable.mango_pic);fruitList.add(mango);}}
}
2.实现横向滚动和瀑布流布局
横向滚动:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="100dp"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/fruit_image"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"/><TextViewandroid:id="@+id/fruit_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:layout_marginTop="10dp"/></LinearLayout>
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
瀑布流布局:
瀑布流布局应该将fruit_item.xml中的LinearLayout的宽度改为match_parent,因为瀑布流布局的宽度应该是根据布局的列数来自动适配的
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
3.RecyclerView的点击事件
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);final ViewHolder viewHolder = new ViewHolder(view);viewHolder.fruitView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {int position = viewHolder.getAdapterPosition();Fruit fruit = mFruitList.get(position);Toast.makeText(v.getContext(),"你点击了"+fruit.getFruitName()+"子项外层布局",Toast.LENGTH_SHORT).show();}});viewHolder.fruitImage.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {int position = viewHolder.getAdapterPosition();Fruit fruit = mFruitList.get(position);Toast.makeText(v.getContext(),"你点击了"+fruit.getFruitName()+"图片部分",Toast.LENGTH_SHORT).show();}});return viewHolder;
}
完!
第一行代码-第二版(郭霖著)笔记三(UI控件)相关推荐
- 第一行代码-第二版(郭霖著)笔记五(Broadcast Receiver)
目录 一.广播机制简介 二.接收系统广播 1.动态注册监听网络变化 2.静态注册实现开机启动 三.发送自定义广播 1.发送标准广播 2.发送有序广播 五.广播的最佳实践---实现强制下线功能 一.广播 ...
- 图灵直播|《第一行代码》作者郭霖在线Coding,今晚八点,给你留位!
图源来自Pexels "我们为什么需要 Kotlin?答:消失的 Getter 和 Setter.又见空指针.Smart Cast.打日志.再见Utils.晚安ButterKnife--&q ...
- Android第一行代码第二版简要总结
进入安卓的第一本书(简要概括) 第一章 了解大体Android 1.Android系统架构 Linux内核层:为Android设备的各种硬件提供了底层的驱动. 系统运行库层:通过c/c++库来提供主要 ...
- 第一行代码-第二版(郭霖著)笔记六(持久化技术)
目录 一.持久化技术简介 二.文件存储 1.将数据存储到文件中 2.从文件中读取数据 三.SharedPreference存储 1.将数据存储到SharedPreferences中 2.从Shared ...
- 第一行代码-第二版(郭霖著)笔记十一(高级技巧)
目录 一.全局获取Context的技巧 二.使用Intent传递对象 1.Serializable方式 2.Parcelable方式 三.定制自己的日志工具 四.调试Android程序 五.深色主题 ...
- 第一行代码-第二版(郭霖著)笔记四(Fragment)
目录 一.碎片是什么 二.碎片的使用方式 1.碎片的简单用法 2.动态添加碎片 3.在碎片中模拟返回栈 4.碎片和活动之间的通信 三.碎片的生命周期 1.碎片的状态和回调方法 四.动态加载布局的技巧 ...
- 《第一行代码》作者郭霖大神安卓问题解答
列举了几个郭大神解答的有关Android的问题,虽然只有几个问题,但是基本涵盖了各个安卓开发阶段的困惑,郭大神的回答简洁深刻,收获颇丰. 1.工作有点吃力怎么办? 首先你要自信,公司都信任你了,你又何 ...
- 第一行代码第二版6.4.1小节创建数据库中遇到adb shell出错的问题
该小节中我们照着作者说的一步步写完相应的代码,并运行程序,最后需要使用adb shell来对数据库和表的创建情况进行检查. 可是当配置好环境变量之后,在命令行终端输入adb shell结果如下所示: ...
- 第一行代码(第二版)全书代码下载
Github地址: https://github.com/newcaoguo/booksource
- 第一行代码-ListViewDemo(2)-读书笔记
对应第一行代码的114页 activity_main.xml <?xml version="1.0" encoding="utf-8"?> < ...
最新文章
- ASP.NET中如何防范SQL注入式攻击
- ASP 投票系统所用技术小结
- 怎么获取codeforces的数据_手把手教你学会新媒体运营——如何通过数据分析来优化新媒体运营...
- VMM系列之VMM角色介绍以及创建运行方式账户
- 肖婧医生直播讲稿整理
- 【ArcGIS遇上Python】ArcGIS批量处理栅格影像(NDVI)归一化完整案例代码
- tomcat(3)连接器
- mysql锁表查询_Mysql数据库锁情况下开启备份导致数据库无法访问处理分享
- 人人都是程序员的节奏,Python 纳入高考
- 程序导致IIS服务器应用程序池停止
- arc和非arc完美支持
- iOS应用商店审核指南
- Linux安装GO语言环境
- 2、ARM嵌入式系统:LED初始化
- 徐州2018年大学计算机比赛,2018年第四届徐州市中小学生学科综合能力大赛获奖名单!权威发布!【五年级】...
- 微信小程序开发入门(API)
- linux启动分区丢,Linux装机因为分区丢失引导解决办法
- ORM框架的简单介绍
- 设计思维——科学提升创造力的方法
- 毕设分享:基于STM32两轮自平衡小车 含源码、原理图及PCB文件