幽映每白日,清辉照衣裳。这篇文章主要讲述android常用控件和布局相关的知识,希望能为你提供帮助。
目录
- 控件
- TextView
- Button
- EditText
- ImageView
- ProgressBar
- AlertDialog
- ProgressDialog
- ListView
- ListView的简单用法
- 定制ListView界面
- RecyclerView
- 布局
- 线性布局LinearLayout
- 相对布局RelativeLayout
- 帧布局FrameLayout
- 百分比布局PercentFrameLayout和PercentRelativeLayout
- 表格布局TableLayout
- 创建自定义控件
- 引入布局
- 自定义控件
控件 TextView??android中所有控件都有android:layout_width和android:layout_height这两个属性。这两个属性的可选值有3个:match_parent,fill_parent和wrap_parent。其中,match_parent和fill_parent意义相同,官方更推荐使用match_parent。
<
?xml version="
1.0"
encoding="
utf-8"
?>
<
LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:orientation="
vertical"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
>
<
!-- gravity属性为文字的对齐方式,可选值有top,bottom,left,right和center,可以使用'
|'
来分隔多个值 -->
<
TextView
android:id="
@+id/text_view"
android:layout_width="
match_parent"
android:layout_height="
wrap_content"
android:textColor="
#00FFEA"
android:gravity="
center"
android:textSize="
24sp"
android:text="
This is a TextView!"
/>
<
/LinearLayout>
文章图片
Button??默认情况下,系统会将button内的英文自动转换为大写,如果这不是你想要的效果,可以将textAllCaps属性设为false。
<
?xml version="
1.0"
encoding="
utf-8"
?>
<
LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:orientation="
vertical"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
>
<
Button
android:id="
@+id/button"
android:layout_width="
match_parent"
android:layout_height="
wrap_content"
android:text="
I am a button."
android:textAllCaps="
false"
android:textColor="
#ff0000"
/>
<
/LinearLayout>
文章图片
可以为button控件的点击事件注册一个监听器:
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "
You clicked the button"
, Toast.LENGTH_SHORT).show();
}
});
}
}
文章图片
??当然了,如果觉得使用匿名内部类的方式来注册监听器不是很直观,也可以使用实现View.OnClickListener接口的方法来注册事件监听。
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
}@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
Toast.makeText(MainActivity.this, "
You clicked the button"
, Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
文章图片
EditText
<
?xml version="
1.0"
encoding="
utf-8"
?>
<
LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:orientation="
vertical"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
>
<
!-- hint表示输入框中的一段提示性文本 -->
<
EditText
android:id="
@+id/edit_text"
android:layout_width="
match_parent"
android:layout_height="
wrap_content"
android:hint="
Type something here!"
android:maxLines="
2"
/>
<
!-- maxLines表示输入框中可向下拓展的最大行数,超过这个行数则会产生滚动 -->
<
/LinearLayout>
文章图片
可以结合按钮和输入框来做一些事情:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
editText = (EditText) findViewById(R.id.edit_text);
button.setOnClickListener(this);
}@Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.button:
// 在按钮的点击事件处理函数中得到输入框的输入并以toast的形式显示出来
String inputText = editText.getText().toString();
Toast.makeText(MainActivity.this, inputText, Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
文章图片
ImageView
<
?xml version="
1.0"
encoding="
utf-8"
?>
<
LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:orientation="
vertical"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
>
<
ImageView
android:id="
@+id/img1"
android:layout_width="
wrap_content"
android:layout_height="
wrap_content"
android:src=https://www.songbingjia.com/android/"
@drawable/img_1"
/>
<
Button
android:id="
@+id/button"
android:layout_width="
match_parent"
android:layout_height="
wrap_content"
android:text="
I am a button."
android:textAllCaps="
false"
android:textColor="
#ff0000"
/>
<
/LinearLayout>
文章图片
可以在程序中通过代码动态的更改ImageView中的图片,修改MainActivity的代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private ImageView img1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
img1= (ImageView) findViewById(R.id.img1);
button.setOnClickListener(this);
}@Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.button:
// 点击按钮后改变图片
img1.setImageResource(R.drawable.img_2);
break;
default:
break;
}
}
}
文章图片
ProgressBar
<
?xml version="
1.0"
encoding="
utf-8"
?>
<
LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:orientation="
vertical"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
>
<
Button
android:id="
@+id/button"
android:layout_width="
match_parent"
android:layout_height="
wrap_content"
android:text="
I am button."
android:textAllCaps="
false"
android:textColor="
#ff0000"
/>
<
ProgressBar
android:id="
@+id/progress_bar"
android:layout_width="
match_parent"
android:layout_height="
wrap_content"
/>
<
/LinearLayout>
文章图片
??这时我们可能会注意到一个问题,旋转的进度条表示程序正在加载数据,而数据总会有加载完的时候,如何让进度条在数据加载完成后就消失呢?
??这就需要用到android:visibility控件可见属性进行指定,它的可选值有3种:visible,invisible和gone。visible表示控件是可见的,是默认值;invisible表示控件不可见,但它仍然会占据着原来的位置,可以理解为控件变为全透明状态了;gone则表示控件不仅不可见,而且不会在占用任何屏幕控件。
??除了可以直接设置控件的xml属性android:visibility来指定控件的可见性,还可以在代码中使用setVisibility()方法指定控件的可见与否,可以向它传入View.VISIBLE,View.INVISIBLE和View.GONE这3个值。
接下来我们就来实现当数据加载完成后进度条消失的效果:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button button;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
button.setOnClickListener(this);
}@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
// 通过getVisibility()来判断当前进度条是否可见
if(progressBar.getVisibility() == View.GONE) {
progressBar.setVisibility(View.VISIBLE);
} else {
progressBar.setVisibility(View.GONE);
}
break;
default:
break;
}
}
}
文章图片
另外,默认情况下,进度条是圆形样式,可以使用style属性将它指定为水平进度条:
<
LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:orientation="
vertical"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
>
...<
ProgressBar
android:id="
@+id/progress_bar"
android:layout_width="
match_parent"
android:layout_height="
wrap_content"
style="
?android:attr/progressBarStyleHorizontal"
android:max="
100"
/>
<
!-- 给进度条指定max最大值100 -->
<
/LinearLayout>
文章图片
将进度条改为水平进度条后,我们就可以在程序中动态的更新进度条的进度值:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button button;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
button.setOnClickListener(this);
}@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
// 使用getProgress()获取当前的进度值
int progress = progressBar.getProgress();
progress = progress + 10;
progressBar.setProgress(progress);
break;
default:
break;
}
}
}
文章图片
AlertDialog??AlertDialog可以在当前的界面中弹出一个对话框,这个对话框是置顶于所有界面元素之上的,能够屏蔽掉其他控件的交互能力(模态窗口)。因此AlertDialog一般用于提示一些非常重要的内容或警告信息。
下面我们来看看怎么使用AlertDialog控件:
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.*;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
}@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:// 点击事件是由R.id.button发起的
// 首先构造一个AlertDialog控件对象
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("
This is a 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 which) {}
});
// 显示对话框
dialog.show();
break;
default:
break;
}
}
}
文章图片
ProgressDialog??ProgressDialog和AlertDialog有点类似,都可以在界面上弹出一个对话框并屏蔽其他控件的交互能力。但不同的是,ProgressDialog会在对话框中显示一个进度条,一般用于表示当前操作比较耗时,让用户耐心的等待。
它的用法和AlertDialog很类似:
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.*;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
}@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
// 首先构造一个AlertDialog控件对象
ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setTitle("
This is a Dialog"
);
progressDialog.setMessage("
Something important."
);
progressDialog.setCancelable(true);
// 允许取消progressDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
Toast.makeText(MainActivity.this, "
你点击了取消"
, Toast.LENGTH_SHORT).show();
}
});
// 显示对话框
progressDialog.show();
break;
default:
break;
}
}
}
文章图片
ListView??ListView应该可以算是Android中最常用的控件之一,几乎所有的应用程序都会用到它。
??由于手机屏幕空间是有限的,所以能够一次性在屏幕上显示的内容并不多,当我们的程序中有大量的数据需要展示的时候,就可以借助ListView来实现。
??ListView允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内,同时屏幕上原有的数据则会滚动出屏幕。事实上,我们几乎每天都在接触这个控件,比如查看QQ聊天记录,翻阅微博最新消息,等等。
ListView的简单用法
首先给程序一个布局:
<
LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
>
<
ListView
android:id="
@+id/list_view"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
/>
<
/LinearLayout>
在xml布局中加入ListView还算简单,下面看一看MainActivity中的代码:
public class MainActivity extends AppCompatActivity {
private String[] data = https://www.songbingjia.com/android/{
"
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);
// 定义一个数组适配器adapter(上述数组中的元素都是字符串)
ArrayAdapter<
String>
adapter = new ArrayAdapter<
String>
(MainActivity.this, android.R.layout.simple_list_item_1, data);
// 使用android.R.layout.simple_list_item_1, data作为ListView子项布局的id,这是一个Android内置的布局文件,里面只有一个TextView,可用于简单地显示一段文本
ListView listView = (ListView) findViewById(R.id.list_view);
// listView应用这个适配器
listView.setAdapter(adapter);
}
}
??ListView中的展示数据可以是从数据库中读取出来的,也可以是从网上下载下来的,这里我们就简单使用一个data数组来测试。
文章图片
定制ListView界面
只能显示一段文本的ListView实在是太单调了,我们可以对ListView做一些个性化的定制。
下面的例子中,我们要在每个列表项前面加上一张图片。
首先创建一个实体类,作为ListView适配器的适配类型。新建类Fruit:
public class Fruit {
private String name;
// 水果的名称
private int imageId;
// 对应的图片的资源idpublic Fruit(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}public String getName() {
return name;
}public int getImageId() {
return imageId;
}
}
然后需要为ListView子项指定一个我们自定义的布局,新建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"
>
<
!--
ListView中的每一项都对应有一个固定的布局文件,前面我们使用的是内置的android.R.layout.simple_list_item_1.xml,
这里为了将图片和水果名称字符串都放在ListView中的一项中,我们使用自定义布局文件
-->
<
ImageView
android:id="
@+id/fruit_image"
android:layout_width="
wrap_content"
android:layout_height="
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。新建类FruitAdapter:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class FruitAdapter extends ArrayAdapter<
Fruit>
{
private int resourceId;
public FruitAdapter(Context context,int textViewResourceId,List<
Fruit>
objects) {
// 可见,我们的自定义适配器FruitAdapter,在真正的适配部分其实还是调用的ArrayAdapter父类的构造方法
super(context, textViewResourceId, objects);
resourceId = textViewResourceId;
}@Override
// 重写ArrayAdapter的getView()方法,这个方法在每个子项滚动到屏幕内时会自动调用
public View getView(int position,View convertView,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中的代码了:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {private List<
Fruit>
fruitList = new ArrayList<
Fruit>
();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
// 初始化水果数据,初始化fruitList[ ]
FruitAdapter adapter = new FruitAdapter(MainActivity.this, R.layout.fruit_item, fruitList);
ListView listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
// 设定适配器
// 为ListView中的每一项都添加一个点击事件监听器
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<
?>
parent, View view, int position, long id) {
Fruit fruit = fruitList.get(position);
// 得到点击位置处显示的对应fruitList中的元素
Toast.makeText(MainActivity.this, fruit.getName(), Toast.LENGTH_SHORT).show();
}
});
}private void initFruits() {
// fruitList列表中的每一项内容都是Fruit类型
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);
}
}
}
文章图片
文章图片
RecyclerView??ListView的功能是非常强大的,但也并不是没有缺点,如果我们不使用一些技巧来提示它的运行效率,那么它的性能会非常差。还有,ListView的扩展性也不够好,它只能实现纵向滚动的效果,如果想实现横向滚动的话,ListView就无能为力了。
??为此,Android提供了一个更强大的滚动控件——RecycleView
布局 线性布局LinearLayout线性布局内控件按水平或垂直方向顺次排布。
<
!-- android命名空间只需要在最顶层的布局中声明一次 -->
<
LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
android:orientation="
vertical"
>
<
Button
android:id="
@+id/btn1"
android:layout_width="
match_parent"
android:layout_height="
wrap_content"
android:text="
I am btn1."
android:textAllCaps="
false"
android:textColor="
#ff0000"
/>
<
Button
android:id="
@+id/btn2"
android:layout_width="
match_parent"
android:layout_height="
wrap_content"
android:text="
I am btn2."
android:textAllCaps="
false"
android:textColor="
#ff0000"
/>
<
Button
android:id="
@+id/btn3"
android:layout_width="
match_parent"
android:layout_height="
wrap_content"
android:text="
I am btn3."
android:textAllCaps="
false"
android:textColor="
#ff0000"
/>
<
Button
android:id="
@+id/btn4"
android:layout_width="
match_parent"
android:layout_height="
wrap_content"
android:text="
I am button4."
android:textAllCaps="
false"
android:textColor="
#ff0000"
/>
<
LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
android:orientation="
horizontal"
android:gravity="
center"
>
<
!-- 嵌套布局 -->
<
Button
android:id="
@+id/btn5"
android:layout_width="
wrap_content"
android:layout_height="
wrap_content"
android:text="
I am btn5"
android:textAllCaps="
false"
android:textColor="
#0000ff"
/>
<
Button
android:id="
@+id/btn6"
android:layout_width="
wrap_content"
android:layout_height="
wrap_content"
android:text="
I am btn6"
android:textAllCaps="
false"
android:textColor="
#0000ff"
/>
<
Button
android:id="
@+id/btn7"
android:layout_width="
wrap_content"
android:layout_height="
wrap_content"
android:text="
I am btn7"
android:textAllCaps="
false"
android:textColor="
#0000ff"
/>
<
Button
android:id="
@+id/btn8"
android:layout_width="
wrap_content"
android:layout_height="
wrap_content"
android:text="
I am btn8"
android:textAllCaps="
false"
android:textColor="
#0000ff"
/>
<
/LinearLayout>
<
/LinearLayout>
文章图片
相对布局RelativeLayout相对布局可以通过相对定位的方式让控件出现在布局的任意位置上。
<
?xml version="
1.0"
encoding="
utf-8"
?>
<
RelativeLayout xmlns:android="
http://schemas.android.com/apk/res/android"
xmlns:tools="
http://schemas.android.com/tools"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
>
<
Button
android:id="
@+id/btn1"
android:layout_width="
wrap_content"
android:layout_height="
wrap_content"
android:layout_alignParentLeft="
true"
android:layout_alignParentTop="
true"
android:text="
button 1"
/>
<
Button
android:id="
@+id/btn2"
android:layout_width="
wrap_content"
android:layout_height="
wrap_content"
android:layout_alignParentRight="
true"
android:layout_alignParentTop="
true"
android:text="
button 2"
/>
<
Button
android:id="
@+id/btn3"
android:layout_width="
wrap_content"
android:layout_height="
wrap_content"
android:layout_centerInParent="
true"
android:text="
button 3"
/>
<
Button
android:id="
@+id/btn4"
android:layout_width="
wrap_content"
android:layout_height="
wrap_content"
android:layout_alignParentBottom="
true"
android:layout_alignParentLeft="
true"
android:text="
button 4"
/>
<
!-- 其内控件可相对于其他控件或父容器排列 -->
<
/RelativeLayout>
文章图片
帧布局FrameLayout帧布局内所有控件默认都会摆放在布局的左上角。
<
FrameLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
>
<
TextView
android:id="
@+id/text"
android:layout_width="
wrap_content"
android:layout_height="
wrap_content"
android:text="
This is TextView"
/>
<
ImageView
android:id="
@+id/img"
android:layout_width="
wrap_content"
android:layout_height="
wrap_content"
android:src=https://www.songbingjia.com/android/"
@mipmap/ic_launcher"
/>
<
/FrameLayout>
文章图片
百分比布局PercentFrameLayout和PercentRelativeLayout??前面提到的LinearLayout,RelativeLayout和FrameLayout都是从Android 1.0版本就开始支持了,一直沿用到现在,可以说是满足了绝大多数场景的界面设计需求。不过细心的你还是可以发现,除了LinearLayout支持使用layout_weight属性来实现按比例指定控件大小的功能外,其余两种布局都不支持。比如说如果要使用RelativeLayout来实现让两个按钮平分布局宽度的效果是很困难的。
??为此,Android引入了一种全新的布局方式来解决该问题——百分比问题。在这种布局中,我们可以不再使用wrap_content,match_parent等方式来指定控件的大小,而是允许直接指定控件在布局中所占的百分比,这样一来,就可以轻松实现平分布局甚至是任意比例分割布局的效果。
【android常用控件和布局】??由于LinearLayout本身已经支持按比例指定控件大小了,因此百分比布局只为FrameLayout和RelativeLayout进行了功能扩展,提供了PercentFrameLayout和PercentRelativeLayout这两个全新的布局。
??android团队将百分比布局定义在了support库中,只需在build.gradle中添加百分比布局库的依赖,就能保证百分比布局在所有系统版本上都可以使用。在build.gradle(Module:app)中添加一行:
dependencies {
implementation '
com.android.support:percent:28.0.0'
}
然后就可以使用百分比布局了,因为百分比布局不是直接内置在SDK中的,所以要写出完整的包名。
<
android.support.percent.PercentFrameLayout
xmlns:android="
http://schemas.android.com/apk/res/android"
xmlns:app="
http://schemas.android.com/apk/res-auto"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
>
<
Button
android:id="
@+id/button1"
android:text="
Button 1"
android:layout_gravity="
left|top"
app:layout_widthPercent="
50%"
app:layout_heightPercent="
50%"
/>
<
Button
android:id="
@+id/button2"
android:text="
Button 2"
android:layout_gravity="
right|top"
app:layout_widthPercent="
50%"
app:layout_heightPercent="
50%"
/>
<
Button
android:id="
@+id/button31"
android:text="
Button 3"
android:layout_gravity="
left|bottom"
app:layout_widthPercent="
50%"
app:layout_heightPercent="
50%"
/>
<
Button
android:id="
@+id/button4"
android:text="
Button 4"
android:layout_gravity="
right|bottom"
app:layout_widthPercent="
50%"
app:layout_heightPercent="
50%"
/>
<
/android.support.percent.PercentFrameLayout>
文章图片
表格布局TableLayout
<
TableLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:layout_width="
match_parent"
android:layout_height="
match_parent"
android:stretchColumns="
1"
>
<
!-- 如果某一行控件的总宽不能铺满父容器,则拉伸第一列以适应屏幕宽度 -->
<
TableRow>
<
!-- TableRow内无法为控件指定宽度 -->
<
TextView
android:layout_height="
wrap_content"
android:text="
Account:"
/>
<
EditText
android:id="
@+id/account"
android:layout_height="
wrap_content"
android:hint="
Input your account"
/>
<
/TableRow>
<
TableRow>
<
TextView
android:layout_height="
wrap_content"
android:text="
Password:"
/>
<
EditText
android:id="
@+id/password"
android:layout_height="
wrap_content"
android:inputType="
numberPassword"
/>
<
/TableRow>
<
TableRow>
<
CheckBox
android:id="
@+id/remember_pass"
android:layout_height="
wrap_content"
/>
<
TextView
android:layout_height="
wrap_content"
android:text="
remember_password"
/>
<
/TableRow>
<
TableRow>
<
Button
android:id="
@+id/login"
android:layout_height="
wrap_content"
android:layout_span="
2"
android:text="
login"
/>
<
/TableRow>
<
/TableLayout>
文章图片
创建自定义控件??所有控件都是直接或间接继承View的,所用的所有部件都直接或间接继承ViewGroup。View是Android中最基本的一种UI组件,它可以在屏幕上绘制一块矩形区域,并能响应这块区域的各种事件。
??因此,我们平常所用的各种组件实际上就是在View的基础上有添加了各自特有的功能。而ViewGroup可以看做是一种特殊的View,它可以包含很多子View和子ViewGroup,是一个用于放置控件和布局的容器。
文章图片
引入布局当系统自带的控件不能满足我们的需求时,可以根据上面的继承关系来实现我们的自定义控件。
下面我们来自定义一个标题栏。
首先新建一个布局title.xml,这是用于actionBar的布局文件。
<
?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="
wrap_content"
android:background="
@drawable/title_bg"
>
<
Button
android:id="
@+id/title_back"
android:layout_width="
wrap_content"
android:layout_height="
wrap_content"
android:layout_gravity="
center"
android:layout_margin="
5dp"
android:background="
@drawable/back_bg"
android:text="
Back"
android:textColor="
#fff"
/>
<
TextView
android:id="
@+id/title_text"
android:layout_width="
0dp"
android:layout_height="
wrap_content"
android:layout_gravity="
center"
android:layout_weight="
1"
android:gravity="
center"
android:text="
Title Text"
android:textColor="
#fff"
android:textSize="
24sp"
/>
<
Button
android:id="
@+id/title_edit"
android:layout_width="
wrap_content"
android:layout_height="
wrap_content"
android:layout_gravity="
center"
android:layout_margin="
5dp"
android:background="
@drawable/edit_bg"
android:text="
Edit"
android:textColor="
#fff"
/>
<
/LinearLayout>
然后将这个布局引入到主布局文件activity_main.xml中(使用include标签):
<
?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"
>
<
include layout="
@layout/title"
/>
<
/LinearLayout>
可以在app中的每一个布局中引入title.xml,这样每个页面就都拥有我们自定义的标题栏了。
另外,由于android系统自带有标题栏,所以要将自带的标题栏隐藏掉:
public class MainActivity extends AppCompatActivity {@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar titleBar = getSupportActionBar();
if(titleBar != null)
titleBar.hide();
}
}
文章图片
back_bg.png | edit_bg.png | title_bg.png |
---|---|---|
文章图片 | 文章图片 | 文章图片 |
新建java类TitleLayout,继承自LinearLayout类:
文章图片
public class TitleLayout extends LinearLayout {public TitleLayout(Context context, AttributeSet attrs) {
// 将xml中设置的一堆属性全部传给父类LinearLayout的构造函数
super(context, attrs);
// 使用from()加载布局title.xml,父布局是TitleLayout本身
LayoutInflater.from(context).inflate(R.layout.title, this);
Button titleBack = (Button) findViewById(R.id.title_back);
Button titleEdit = (Button) findViewById(R.id.title_edit);
// 为titleBack控件即返回按钮添加事件监听
titleBack.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
((Activity) getContext()).finish();
// 销毁当前上下文活动,退出应用
}
});
titleEdit.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "
You clicked Edit button"
, Toast.LENGTH_SHORT).show();
}
});
}
}
??然后在主布局activity_main.xml中使用TitleLayout布局,由于TitleLayout是我们自定义的,没有内置在SDK中,所以我们在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"
>
<
com.example.uiwidgetdemo.TitleLayout
android:layout_width="
match_parent"
android:layout_height="
wrap_content"
>
<
/com.example.uiwidgetdemo.TitleLayout>
<
/LinearLayout>
文章图片
推荐阅读
- Android中三种创建监听器的方法
- [Trouble shooting] Alt-A shortcut taken by another app and conflict with Emacs' M-a
- Android Activity间跳转与传递数据
- flume 启动agent报No appenders could be found for logger的解决
- 抖音BoostMultiDex优化实践(Android低版本上APP首次启动时间减少80%)
- Win8怎样备份IE浏览器收藏夹 IE浏览器备份收藏夹的办法【图】
- Windows 8系统自带截图工具无法另存为图片怎样办【图】
- Win8系统货币价值计算工具的运用办法【图】
- Win8系统怎样打开迅速打开选项 win8开始打开项失去了怎样办