安卓应用采用View组件进行界面布局,可以通过两种方式进行布局,分别是XML文件和Java代码。
其中采用XML文件进行布局是较好的方式,因为这样可以将XML文件和Java代码分开编写,使得项目结构变得更加清晰。
- 简单的图片浏览器
下面是一个XML文件和Java代码混用的案例,编写一个简单的图片浏览器。
首先编写一个LinearLayout的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity"
android:id="@+id/root"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
布局文件的内容非常简单,其中比较重要的是id属性,我们在java代码里面需要通过id来获取这个线性布局容器。
接着,我们定义一个MainActivity类,并且给线性布局容器添加一个ImageView容器来显示图片,ImageView容器也是可以添加按钮监控的,在重载的onClick()方法中,我们需要编写替换下一张图片的代码。
public class MainActivity extends Activity {
// 定义一个访问图片的数组
int[] images = new int[]{
R.drawable.ic_launcher_background, R.drawable.ic_launcher_foreground
};
int currentImage = 0;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 加载布局文件
setContentView(R.layout.main);
// 获取线性布局容器
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.root);
// 创建ImageView组件
ImageView imageView = new ImageView(this);
// 将ImageView组件添加到线性布局容器中
linearLayout.addView(imageView);
// 初始化时显示第一张图片
imageView.setImageResource(images[0]);
// 给ImageView添加按键监控
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 替换为下一张图片
imageView.setImageResource(images[++currentImage % images.length]);
}
});
}
}
最后获得的效果就是,界面正上方有一个显示图片的区域,当我们点击该图片的时候,显示的图片就会改变。
在安卓应用中,View组件只是一个空白的矩形区域,没有任何内容,对于android的其他UI组件来说,他们都继承了View组件,然后在View组件提供的空白区域上绘制外观。当andorid提供的UI组件不能满足我们的需求的时候,我们也可以通过继承View来自定义组件。
-
跟随手指的小球
我们首先需要创建一个DrawView容器,然后重写onDraw()方法和onTouchEvent()方法,前者用于绘制小球,后者用于获取当前触碰的坐标,用于更新小球位置。
public class DrawView extends View {
// 定义初始坐标
public float currentX = 50;
public float currentY = 50;
// 定义并创建画笔
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
}
// 重载onDraw()方法,当组件将要绘制他的内容时回调该方法进行绘制
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 设置画笔颜色
paint.setColor(Color.RED);
// 绘制小球
canvas.drawCircle(currentX, currentY, 15, paint);
}
// 为该组件的触碰事件重写事件处理方法
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
// 获取当前坐标
currentX = event.getX();
currentY = event.getY();
// 通知当前组件重绘自己
invalidate();
// 返回true表明该处理方法已经处理该事件
return true;
}
}
接着在LinearLayout容器中添加DrawView容器即可
public class CustomViewActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取线性布局容器
LinearLayout linearLayout = findViewById(R.id.root);
// 创建DrawView组件
DrawView drawView = new DrawView(this);
// 设置自定义组件的最小宽度和高度
drawView.setMinimumWidth(300);
drawView.setMinimumHeight(500);
linearLayout.addView(drawView);
}
}
运行程序可以发现小球会根据触碰的坐标更新位置。
安卓SDK提供了很多布局管理器,他们都是ViewGroup的子类。
-
计算器界面
使用GridLayout可以编写一个计算器界面
首先编写布局XML文件,布局文件中包含文本框和按钮部分
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="6"
android:columnCount="4"
android:id="@+id/calculator">
<!-- 定义一个横跨4列的文本框 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_columnSpan="4"
android:textSize="50sp"
android:layout_marginLeft="2pt"
android:layout_marginRight="2pt"
android:padding="3pt"
android:layout_gravity="right"
android:background="#eee"
android:textColor="#000"
android:text="0" />
<!-- 定义一个横跨4列的按钮 -->
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_columnSpan="4"
android:text="清除"
/>
</GridLayout>
接着在Java代码中加载GridLayout布局,并且添加按钮控件
public class CalculatorActivity extends Activity {
GridLayout gridLayout;
// 定义16个按钮的文本
String[] chars = new String[] {
"7", "8", "9", "÷",
"4", "5", "6", "×",
"1", "2", "3", "﹣",
".", "0", "=", "﹢"
};
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calculator);
gridLayout = (GridLayout) findViewById(R.id.calculator);
// 加载16个按钮
for(int i=0; i<chars.length; i++){
Button bn = new Button(this);
bn.setText(chars[i]);
// 设置按钮的字号大小
bn.setTextSize(40);
// 设置按钮四周的空白区域
bn.setPadding(5, 35, 5, 35);
// 指定该组件所在的行
GridLayout.Spec rowSpec = GridLayout.spec(i/4 + 2);
// 指定该组件所在的列
GridLayout.Spec colSpec = GridLayout.spec(i % 4);
GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpec, colSpec);
// 指定该组件占满父容器
params.setGravity(Gravity.FILL);
gridLayout.addView(bn, params);
}
}
}
运行后就呈现出一个占满整个屏幕的计算器界面。