Android的UI开发
一.常用控件
android:layout_Width和android:layout_height
指定空间的宽度和高度.可选值有:match_parent:
表示让当前控件的大小和父布局的大小一样,由父布局来决定当前控件的大小.wrap_content:
表示当前控件的大小能刚好包含住里面的内容,由空间内容决定当前控件的大小.fill_parent:
与match_parent
意义相同(存在少部分版本问题)
1.TextView
属性 | 概括 | 备注 |
text | 显示的内容 | |
gravity | 文字对齐方式 | top,bottom,left,right,center等参数 |
textSize | 字体大小 | sp做单位 |
textSize | 字体颜色 |
2.Button
系统会自动将字体转为大写
属性 | 概括 | 备注 |
textAllCape | 禁用默认转化 | true,false参数 |
3.EditText
该组件允许用户在控件里输入和编辑内容,并可以在程序中对这些内容进行处理.
属性 | 概括 | 备注 |
hint | 灰底提示信息 | |
maxLines | 指定提示信息的最大长度 | 1~x行 |
4.ImageView
该组件用于在界面上展示的一个控件,它可以yu让我们的程序界面变的更加丰富.
属性 | 概括 | 备注 |
src | 定义指定的图片 | |
layout_width | 指定图片宽度 | |
layout_height | 指定图片高度 |
5.ProgressBar
该控件用于在界面上显示一个进度条,表示程序正在加载一些数据
属性 | 概括 | 备注 |
visibility | 可见属性 | visible,invisible,gone参数.(visible是默认可见的,invisble不可见,但占据空间,gone不可见,不占据空间) |
style | 控制进度条样式 | |
max | 设置最大值 |
6.AlertDialog
AlertDialog可以在当前的界面弹出对话框,至于所有界面之上,屏蔽掉其他控件的交互能力
实现View.onClickListener接口重写onclick方法
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.button:
//创建AlertDialog实例,为对话框设置标题,内容,是否可用Back键关闭对话框等属性.
AlertDialog.Builder dialog=new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("This is Dialog");
dialog.setMessage("Something important.");
dialog.setCancelable(false);
//为对话框设置确定按钮的点击事件
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
//设置取消按钮的点击事件
dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whick) {
}
});
//将对话框显示出来
dialog.show();
break;
default:
break;
}
}
7.ProgressDialog
该控件与AlertDialog有些类似,不同点在于ProgressDialog在对话框中显示一个进度条
二.四种基本布局
1.线性布局(LinearLayout)
属性 | 概括 | 备注 |
orientation | 结构方向 | vertical(垂直),horizontal(水平).排列方式是horizontal时,内部的空间就绝对不能将宽度指定为match_parent.排列方式是vertical时,内部的空间就绝对不能将高度指定为match_parent. |
layout_gravity | 对齐方式 | top,center_vertical,buttom |
layout_weight | 比例控制控件大小 |
2.相对布局(RelativeLayout)
属性 | 概括 | 备注 |
layout_alignParentLeft | 左对齐 | true/false |
layout_alignParentRight | 右对齐 | true/false |
layout_alignParentTop | 顶端 | true/false |
layout_alignParentBottom | 底部 | trua/false |
layout_centerInParent | 剧中 | true/false |
layout_above | 相对于其他控件位置 | |
layout_above | 置于控件上方 | |
layout_below | 置于控件下方 | |
layout_toLeftOf | 置于控件左侧 | |
layout_toRightOf | 置于控件右侧 | |
layout_alignLeft | 一个控件的左边缘和另一个控件的左边缘对齐 | |
layout_alignRight | 一个控件的右边缘和另一个控件的右边缘对齐 | |
layout_alignTop | 一个控件的上边缘和另一个控件的上边缘对齐 | |
layout_alignBottom | 一个控件的下边缘和另一个控件的下边缘对齐 |
3.帧布局(FrameLayout)
所有控件默认都摆放在布局的左上角,可以用layout_gravity来进行定位.
4.百分比布局(PercentFrameLayout)
百分比布局只为FrameLayout和RelativeLayout进行功能扩展,LinearLayout本身已经支持比例调控
属性 | 概括 | 备注 |
layout_widthPercent | 宽度 | x% |
layout_heightPercent | 高度 | y% |
5.ListView
1.简单用法
activity_main.xml
<?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"
tools:context=".MainActivity">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
MainActivity.class
Arraydapter适配器,参数1:当前上下文,参数2:ListView子项布局的id,参数3:要是适配的数据.
setAdapter(),将构建好的适配器对象传递进去,使ListView和数据之间的关联就建立完成.
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"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayAdapter<String> adapter=new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1,data);
ListView listView=(ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
}
}
2.定制ListView的界面
定义一个实体类,作为ListView适配器的适配类型.
public class Fruit{
private String name;
private int imageId;
public Fruit(String name,int imageId){
this.name=name;
this.imageId=imageId;
}
public String getName(){
return name;
}
public int getImageId(){
return imageId;
}
}
fruit_item.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">
<ImageView
android:id="@+id/fruit_image"
android:layout_height="wrap_content"
android:layout_width="wrap_content"/>
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"/>
</LinearLayout>
创建自定义适配器,继承ArrayAdapter,将泛型指定为Fruit类FruitAdaoter
重写父类的一组构造函数,用于将上下文,ListView子项布局的id和数据都传递进来,重写getView()方法,让每一个子项被滚动到屏幕内的时候会被调用.LayoutInflater
的inflate()
方法.参数1:布局文件的资源Id;参数2:(1)当attachToRoot为true时,该方法返回的view对象会自动被添加到root中作为root的一个子控件;
(2).当attachToRoot为false时,该方法返回的view只会获得root的布局属性
如果root为null,则第三个参数无效,且生产的view的getLayoutParams()会返回空,也就是 view不会有布局属性.参数3:true/false
public class FruitAdapter extends ArrayAdapter<Fruit> {
private int resourceId;
public FruitAdapter(@NonNull Context context, int textViewResourceId, @NonNull List<Fruit> objects) {
super(context, textViewResourceId, objects);
resourceId=textViewResourceId;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Fruit fruit=getItem(position);//获取当前项的Fruit实例
//为子项加载传入的布局
View view= LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
ImageView fruitImage=(ImageView) view.findViewById(R.id.fruit_image);
TextView fruitName=(TextView) view.findViewById(R.id.fruit_name);
fruitImage.setImageResource(fruit.getImageId());
fruitName.setText(fruit.getName());
return view;
}
}
MainActivity.class
用于初始化水果数据,进行对应水果名字和图片的传入
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();//初始化水果数据
FruitAdapter adapter=new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);
ListView listView=(ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
}
private void initFruits(){
for(int i=0;i<2;i++){
Fruit apple=new Fruit("Apple",R.drawable.abc_vector_test);
fruitList.add(apple);
...
}
}
}
3.点击事件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();//初始化水果数据
FruitAdapter adapter=new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);
ListView listView=(ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Fruit fruit=fruitList.get(position);
Toast.makeText(MainActivity.this,fruit.getName(),Toast.LENGTH_SHORT).show();
}
});
}
6.滚动控件(RecyclerView)
1.RecyclerView基本用法
在app/build.gradle文件,dependencies闭包添加implementation 'android.recyclerview:recyclerview:1.0.2'
在activity_main.xml
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_View"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
为RecyclerView准备一个适配器
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
@NonNull
@Override
public 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;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Fruit fruit=mFruitList.get(position);
holder.fruitImage.setImageResource(fruit.getImageId());
holder.fruitName.setText(fruit.getName());
}
@Override
public int getItemCount() {
return mFruitList.size();
}
static class ViewHolder extends RecyclerView.ViewHolder{
ImageView fruitImage;
TextView fruitName;
public ViewHolder(View view){
super(view);
fruitImage=(ImageView) view.findViewById(R.id.fruit_image);
fruitName=(TextView) view.findViewById(R.id.fruit_name);
}
}
public FruitAdapter(List<Fruit> fruitList){
mFruitList=fruitList;
}
}
使用RecycleView
```java
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
RecyclerView recyclerView=(RecyclerView) findViewById(R.id.recycler_View);
LinearLayoutManager layoutManager=new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter=new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
}
private void initFruits(){
for(int i=0;i<2;i++){
Fruit apple=new Fruit("Apple",R.drawable.abc_vector_test);
fruitList.add(apple);
.......
}
}
}
2.实现横向滚动和瀑布流布局
横向滚动
修改fruit_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/fruit_image"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_horizontal"/>
<TextView
android:id="@+id/fruit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"/>
</LinearLayout>
在MainActivity中
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
RecyclerView recyclerView=(RecyclerView) findViewById(R.id.recycler_View);
LinearLayoutManager layoutManager=new LinearLayoutManager(this);
//添加进行设置布局的排列方向,默认是纵向排列,此处是横向
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter=new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
}
瀑布流布局
fruit_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="vertical">
MainActivity.classStaggeredGridLayoutManager
的构造函数接收两个参数,参数1:用于指定布局的列数.参数2:指定布局的排列方式,StaggeredGridLayoutManager.VERTICAL
是布局纵向排列.getRandomLengthName()
是为了让排列达到高度不一的瀑布效果.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
RecyclerView recyclerView=(RecyclerView) findViewById(R.id.recycler_View);
// LinearLayoutManager layoutManager=new LinearLayoutManager(this);
// layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
StaggeredGridLayoutManager layoutManager=new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
FruitAdapter adapter=new FruitAdapter(fruitList);
recyclerView.setAdapter(adapter);
}
---------------------------------------
private void initFruits(){
for(int i=0;i<2;i++){
Fruit apple=new Fruit(getRandomLengthName("Apple"),R.drawable.abc_vector_test);
fruitList.add(apple);
......
------------------------------------
private String getRandomLengthName(String name){
Random random=new Random();
int length= random.nextInt(20)+1;
StringBuilder builder=new StringBuilder();
for (int i = 0; i <length ; i++) {
builder.append(name);
}
return builder.toString();
}
3.RecyclerView的点击事件
RecyclerView没有提供注册监视器的方法,需要自己注册.
public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
private List<Fruit> mFruitList;
static class ViewHolder extends RecyclerView.ViewHolder{
ImageView fruitImage;
TextView fruitName;
View fruitView;
public ViewHolder(View view){
super(view);
fruitView=view;
fruitImage=(ImageView) view.findViewById(R.id.fruit_image);
fruitName=(TextView) view.findViewById(R.id.fruit_name);
}
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);
final ViewHolder holder=new ViewHolder(view);
holder.fruitView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position=holder.getAdapterPosition();
Fruit fruit=mFruitList.get(position);
Toast.makeText(view.getContext(), "you clicked view"+fruit.getName(), Toast.LENGTH_SHORT).show();
}
});
holder.fruitImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position= holder.getAdapterPosition();
Fruit fruit=mFruitList.get(position);
Toast.makeText(view.getContext(),"you clicked image"+fruit.getName(),Toast.LENGTH_SHORT).show();
}
});
return holder;
}
.........