Android学习读书笔记之界面编程View和布局管理器,对话框,ViewAnimator,ProgressBar

Android学习读书笔记之界面编程

一.界面编程与视图(View)组件
1.视图组件与容器组件
Android应用的绝大部分UI组件都放在android.widget包及其子包,android.view包及其子包中,Android应用的所有UI组件都继承了View类。

所有的组件都提供了两种方式来控制组件的行为。
1> 在XML布局文件中通过XML属性进行控制。
2> 在Java程序代码中通过调用方法进行控制。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
ViewGroup容器控制其子组件的分布依赖于ViewGroup.LayoutParams, ViewGroup.MarginLayoutParams两个内部类。这两个内部类都提供了一些XML属性,ViewGroup容器中的子组件可以指定这些XML属性。

ViewGroup.LayoutParams支持的XML属性
在这里插入图片描述
支持如下3个属性值:
1> fill_parent: 指定子组件的高度,宽度与父容器组件的高度,宽度相同。
2> match_parent: 该属性值与fill_parent完全相同;
3> wrap_content:指定子组件的大小恰好能包裹它的内容即可。

ViewGroup.MarginLayoutParams用于控制子组件周围的页边距,支持的XML属性如下
在这里插入图片描述

2.使用XML布局文件和Java代码混合控制UI界面
当混合使用XML布局文件和代码来控制UI界面时,习惯上把变化小,行为比较固定的组件放在XML布局文件中管理,而那些变化较多,行为控制较为复杂的组件则交给Java代码来管理。

实例1.简单的图片浏览器
step1. 先在布局文件中定义一个简单的线性布局容器,该布局代码如下:
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:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
</LinearLayout>

step2:在程序中获取该线性布局容器,并往该容器中添加组件:
MainActivity.java

package com.example.simpleadaptertest;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    int [] images = new int [] {
            R.drawable.fruit,
            R.drawable.macao,
            R.drawable.mountain,
    };
    int currentImg = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取LinearLayout布局容器
        LinearLayout main = (LinearLayout) findViewById(R.id.root);
        //程序创建ImageView组件
        final ImageView image = new ImageView(this);
        //将ImageView组件添加到LinearLayout布局容器中
        main.addView(image);
        //初始化时显示第一张图片
        image.setImageResource(images[0]);
        image.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                //改变ImageView里显示的图片
                image.setImageResource(images[++currentImg %images.length]);
            }
        });
    }
}

实际效果:
在这里插入图片描述
在这里插入图片描述
3.开发自定义的View
当Andriod系统提供的UI组件不足以满足项目需求时,开发者可以通过继承View来派生自定义组件。
首先定义一个继承View基类的子类,然后重写View类的一个或多个方法。通常可以被用户重写的方法如下:
在这里插入图片描述
在这里插入图片描述

实例2.跟随手指的小球
当需要开发自定义View时,开发者可以根据需要重写父类的部分方法。

DrawView.java

package com.example.customview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

public class DrawView extends View {

    private final static String TAG = "DrawView";
    public float currentX = 40;
    public float currentY = 50;

    //定义并创建画笔
    Paint p = new Paint();

    public DrawView(Context context){
        super(context);
    }
    public DrawView(Context context, AttributeSet set){
        super(context, set);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        p.setColor(Color.GREEN);
        //绘制一个小圆
        canvas.drawCircle(currentX, currentY, 35, p);
    }

    //为该组件的触碰事件重写事件处理方法
    //这里会调用两次按下和弹起
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        currentX = event.getX();
        currentY = event.getY();

        Log.d(TAG, "event:"+event.getActionMasked());
        if(event.getActionMasked() == event.ACTION_DOWN){
        }else if(event.getActionMasked() == event.ACTION_UP){
        }

        Log.d(TAG, "onTouchEvent: x:"+currentX);
        Log.d(TAG, "onTouchEvent: y:"+currentY);
        //通知当前组件重绘自己
        invalidate();
        //返回true表明该处理方法已经处理该事件
        return true;
    }
}

接下来可以通过Java代码把该组件添加到指定容器中,这样就可以看到该组件的运行效果。

CustomViewActivity.java

package com.example.customview;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.LinearLayout;

public class CustomViewActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        LinearLayout root = (LinearLayout)findViewById(R.id.root);
        //创建DrawView组件
        final DrawView draw = new DrawView(this);
        //设置自定义组件的最小宽度和高度
        draw.setMinimumWidth(800);
        draw.setMinimumHeight(1000);
        root.addView(draw);
    }
}

布局文件

<?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:id="@+id/root"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CustomViewActivity">

</LinearLayout>

实际效果:
在这里插入图片描述
在这里插入图片描述
三.布局管理器

1.线性布局 LinearLayout
2.表格布局 TableLayout
3.帧布局 FrameLayout
实现:霓虹灯效果

使用上面的FrameLayout布局管理器,只是程序启动了一个线程来控制周期性改变这6个TextView的背景色。

MainActivity.java

package com.example.framelayouttest;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity {

    private int currentColor = 0;

    //定义一个颜色数组
    final int [] colors = new int []{
            R.color.color1,
            R.color.color2,
            R.color.color3,
            R.color.color4,
            R.color.color5,
            R.color.color6,
    };

    final int [] names = new int [] {
            R.id.view01,
            R.id.view02,
            R.id.view03,
            R.id.view04,
            R.id.view05,
            R.id.view06
    };

    TextView [] views = new TextView[names.length];

    Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            //表明消息来自本程序所发送的
            if(msg.what == 0x123){
                for(int i = 0; i < names.length; i++){
                    views[i].setBackgroundResource(colors[(i+currentColor) % names.length]);
                }
                currentColor++;
            }
            super.handleMessage(msg);
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceSrate) {
        super.onCreate(savedInstanceSrate);
        setContentView(R.layout.activity_main);

        for(int i = 0; i < names.length; i++){
            views[i] = (TextView)findViewById(names[i]);
        }
        //定义一个线程周期性地改变currentColor变量值
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                //发送一条空消息通知系统改变6个TextView组件的背景色
                handler.sendEmptyMessage(0x123);
				/*
                for(int i = 0; i<names.length; i++){
                    views[i].setBackgroundResource(colors[(i+currentColor) % names.length]);
                }
                currentColor++;
				*/
            }
        },0,2000);
    }
}

实际效果:
在这里插入图片描述
4.相对布局 RelativeLayout
5.网格布局 GridLayout
6.绝对布局 AbsoluteLayout

Android中一般支持如下常用的距离单位:
在这里插入图片描述

四.TextView及其子类
在这里插入图片描述
五.ImageView及其子类
在这里插入图片描述
六.AdapterView及其子类
在这里插入图片描述
七.ProgressBar及其子类
在这里插入图片描述
八.ViewAnimator及其子类

在这里插入图片描述
九.对话框
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值