2019级软件工程应用与实践-人工智能快递柜(代码分析2)

2021SC@SDUSC
第一篇博客中学习了Android Studio的基本使用方式。
第二篇主要是利用了第一周的部分时间和第二周的全部时间来学习Android开发所需要的语法,通过学习,终于可以看懂部分代码了。下面是自己根据网上的教程总结的一些知识点。
第三周将会依照代码进行详细的分析。
Android Studio开发视频教程:
【天哥】Android开发视频教程最新版 Android Studio开发
Android开发从入门到精通(项目案例版

布局

LInearLayout

2019级软件工程应用与实践-人工智能快递柜(代码分析2)
主要属性

android:orientation="vertical"
android:gravity="center_horizontal|bottom"
android:layout_weight="1" // 剩余空间分配占比,用weight标识,不写为0

效果显示:
2019级软件工程应用与实践-人工智能快递柜(代码分析2)

FrameLayout

2019级软件工程应用与实践-人工智能快递柜(代码分析2)
示层叠内容,或者可拖动内容
主要的内容是:

    android:foreground="@mipmap/ic_launcher" //前景,最前面显示的图片,不会被覆盖
    android:foregroundGravity="right|bottom" //前景图片位置设置
TableLayout

2019级软件工程应用与实践-人工智能快递柜(代码分析2)
常用属性:

android:collapseColumns="0,2" // 需要隐藏的列
android:stretchColumns="1" // 可以被拉伸的列
android:shrinkColumns="2" // 可以被收缩的列
  <TableRow>...</TableRow> // 一个行内含有的东西,不写就直接用组件添加一行
GridLayout

2019级软件工程应用与实践-人工智能快递柜(代码分析2)
主要属性:

    android:orientation="vertical" // 默认排序方向
    android:rowCount="3" // 最大行数
    android:columnCount="4" // 最大列数

再java文件中:

gridLayout.getChildCount() // 子UI数量
gridLayout.getChildAt(i) // 返回子UI的View,按index来
布局管理器的嵌套

1.只能有一个根布局管理器,如果需求多个,用一个root包含起来
2.根管理器包含xmlns标记
3.嵌套过多影响性能

基本UI组件

TextView

id => 设置一个组件id,通过findViewById()的方法获取到该对象,然后进行相关设置
layout_width => 组件宽度
layout_height => 组件高度
  wrap_content 自适应大小
  match_parent 与父同
text => 设置文本内容
background => 背景颜色(或背景图片)
textColor => 设置字体颜色
textStyle => 设置字体样式
textSize => 字体大小
gravity => 内容的对齐方向
autoLink => autoLink的属性可以将符合指定格式的文本转换为可单击的超链接形式
drawableTop => TextView上部出现一个图片
shadow =>
  shadowColor属性用来设置阴影颜色,颜色可以再colors.xml中预先配置;
  shadowRadius属性设置模糊程度,数值越大,阴影就越模糊;
  shadowDx属性设置在水平方向上的偏移量,数值越大,则阴影越向右移动;
  shadowDy属性设置在垂直方向上的偏移量,数值越大,则阴影越向下移动。
autoLink => 超链接 web,email,phone,map,all
  textColorLink改颜色
drawableTop =>(drawableLeft、drawableRight、drawableBottom):在TextView的上(左、右、下方放置一个drawable(图片等))

EditText

TextView的子类
hint => 文本框内提示
textColorHint => 设置hint提示文字颜色
inputType =>
  “none”//输入普通字符
  “text”//输入普通字符
  “textCapCharacters”//输入普通字符
  “textCapWords”//单词首字母大小
  textCapSentences"//仅第一个字母大小
  “textAutoCorrect”//前两个自动完成
  “textAutoComplete”//前两个自动完成
  “textMultiLine”//多行输入
  “textImeMultiLine”//输入法多行(不一定支持)
  “textNoSuggestions”//不提示
  “textUri”//URI格式
  “textEmailAddress”//电子邮件地址格式
  “textEmailSubject”//邮件主题格式
  “textShortMessage”//短消息格式
  “textLongMessage”//长消息格式
  “textPersonName”//人名格式
  “textPostalAddress”//邮政格式
  “textPassword”//密码格式
  “textVisiblePassword”//密码可见格式
  “textWebEditText”//作为网页表单的文本格式
  “textFilter”//文本筛选格式
  “textPhonetic”//拼音输入格式
  “number”//数字格式
  “numberSigned”//有符号数字格式
  “numberDecimal”//可以带小数点的浮点格式
  “phone”//拨号键盘
  “datetime”//日期+时间格式
  “date”//日期键盘
  “time”//时间键盘
drawableLeft => 编辑框内左侧绘制图片资源,= Start | 也有Top Bottom Right
drawablePadding => 图片padding
lines => 占几行(显示上)
digits => 设置只接收指定的文本内容
textAlignment => center(居中),inherit(默认,居左边显示),viewStart(居左显示),viewEnd(居右显示),textStart(居左显示),textEnd(居右显示).
extCursorDrawable => 光标颜色
android:textScaleX => 文本水平缩放系数.
android:typeface => hint字体
maxLength => 最多接收文本长度
maxHeight => 文本区域最大高度
minHeight => 文本区域最小高度
scrollHorizontally => 文本超出,是否出现横拉条
ellipsize => 文字过长时,如何显示
  "start”开头省略
  ”end”结尾省略
  ”middle”中间省略
  ”marquee” 跑马灯

// 获取文本内容(Java):
EditText editText = findViewById(R.id.et1);
editText.getText();
Button

TextView 子类
单击事件监听器:
1.匿名内部类-MainActivity

        Button button = findViewById(R.id.b1); // id of button
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //执行代码
            }
        });

2.onClick属性

    public void myClick(View view){
        //执行代码
    }
ImageButton

无text属性
背景设置透明:android:background = “#0000”

RadioButton
    <RadioGroup
        android:id="@+id/rg1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1"
            />
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="2"
            />
    </RadioGroup>

获取选择值
方法一 切换选项获取(MainActivity):

        RadioGroup rg1 = findViewById(R.id.rg1);
        rg1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                RadioButton r = findViewById(checkedId);
                r.getText(); // 返回选择的text
            }
        });

方法二 用按钮获取:
加入到onClick()的执行代码中

        for(int i = 0; i < rg1.getChildCount(); i++) {
            RadioButton r = (RadioButton) rg1.getChildAt(i);
            if(r.isChecked()){
                Toast.makeText(MainActivity.this,"success" + r.getText(),Toast.LENGTH_SHORT).show();
                break;
            }
        }
CheckBox

无需group
监听,先添加id/cb1:

        CheckBox cb1;
        cb1 = findViewById(R.id.cb1);
        cb1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(cb1.isChecked()){
                    cb1.getText(); // 执行代码
                }
            }
        });
DatePicker
public class MainActivity extends AppCompatActivity {
    DatePicker dp;
    int y, m, d;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dp = findViewById(R.id.dp);
        Calendar c = Calendar.getInstance();
        y = c.get(Calendar.YEAR);
        m = c.get(Calendar.MONTH);
        d = c.get(Calendar.DAY_OF_MONTH);
        dp.init(y, m, d, new DatePicker.OnDateChangedListener() {
            @Override
            public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                MainActivity.this.y = year;
                MainActivity.this.m = monthOfYear;
                MainActivity.this.d = dayOfMonth;
                show();
            }
        });
    }
    private void show(){
        String s = y + "年" + (m+1) + "月" + d + "日";
        Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
    }
}
TimePicker
    TimePicker tp;
        tp = findViewById(R.id.tp);
        tp.setIs24HourView(true);
        tp.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
            @Override
            public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
                String s1 = hourOfDay + ":" + minute;
                Toast.makeText(MainActivity.this, s1, Toast.LENGTH_SHORT).show();
            }
        });

大概就是这些

高级UI组件

ProgressBar

style="" 改进度条样式,前面无android:
android:max=“100” 最大进度
android:progress=“40” 当前进度

美化:相关链接
模拟进度条:

public class MainActivity extends AppCompatActivity {
    private ProgressBar pb;
    private int p = 0;
    private Handler mHandler;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pb = findViewById(R.id.pb);
        mHandler = new Handler(){
            @Override
            public void handleMessage(@NonNull Message msg) {
                if(msg.what == 0x111){
                    pb.setProgress(p);
                }else {
                    Toast.makeText(MainActivity.this, "success", Toast.LENGTH_SHORT).show();
                    pb.setVisibility(View.GONE);
                }
            }
        };
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    p = doWork();
                    Message m = new Message();
                    if(p < 100){
                        m.what = 0x111; // 自定义消息代码,0x***
                        mHandler.sendMessage(m);
                    }else{
                        m.what = 0x110;
                        mHandler.sendMessage(m);
                        break;
                    }
                }
            }
            private int doWork(){
                p += Math.random() * 10;
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return p;
            }
        }).start();
    }
}
SeekBar

ProcessBar子类

public class MainActivity extends AppCompatActivity {
    private SeekBar sb;
    private ImageView iv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sb = findViewById(R.id.sb);
        iv = findViewById(R.id.iv);
        sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                iv.setImageAlpha(progress);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                Toast.makeText(MainActivity.this, "start", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                Toast.makeText(MainActivity.this, "end", Toast.LENGTH_SHORT).show();
            }
        });
    }
}
RatingBar

android:numStars=“5” 最大星星数量
android:rating=“0” 默认星星数量
android:stepSize=“0.5” 星星step
android:isIndicator=“false” true则不能改变星星

ImageView

android:src="" 图片文件
android:scaleType="" 缩放方式

fitXY 填充拉伸
center 居中,不缩放,小则截取
centerCrop 锁定长宽比缩放,截取显示
centerInside 锁定长宽比缩放,完全显示
fitCenter 同上,位于*,类似还有fitEnd底部, fitStart顶部
martix 矩阵绘制

android:adjustViewBounds=“true” 自调整图片layout, 需要layout用wrap
android:maxWidth=“90dp” 最大宽
android:maxHeight=“90dp” 最大高
android:tint="#aaff0000" 滤镜,蒙版

ImageSwitcher

分为点击切换和滑动切换

GridView

android:numColumns="" 列数

Adapter

共分为ArrayAdapter
SimpleAdapter
SimpleCursorAdapter
BaseAdapte

Spinner

android:entries="" 列表内容
定义方法:

//(1)数组资源文件 *.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

Activity

2019级软件工程应用与实践-人工智能快递柜(代码分析2)
屏幕翻转的时候会destroy再启动

切换Activity

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                startActivity(intent);
            }
        });

结束(返回)Activity
finish()
刷新:
onCreate(null)
使用Bundle 传递数据
2019级软件工程应用与实践-人工智能快递柜(代码分析2)

intent

属性
Component name

setComponent(ComponentName(包名,类名))
使用 ComponentName 切换 Acitvity

Intent intent = new Intent();
ComponentName componentName = new ComponentName("com.example.intent", "com.example.intent.Detail")
Action 和 Data

设置点击监听,打电话和发短信功能

Extras

putExtras()
getExtras()

Flags

intent.setFlags(intent.FLAG_ACTIVITY_NO_HISTORY); // 用户离开自动关闭

Intent 种类

(一)显式Intent
指定切换对象
(二)隐式Intent
未指定对象
如:打开百度首页

            Intent intent = new Intent();
            intent.setAction(intent.ACTION_VIEW);
            intent.setData(Uri.parse("http://www.baidu.com"));
Intent过滤器

通过标记在AndroidManifest.xml中设定

事件

基于监听器的事件

课设中多次涉及,不再赘述

基于回调的事件

onTouchEvent()
onKeyDown()
onKeyUp()

物理按键事件

onKeyDown()
onKeyUp()
onKeyLongPress()

触摸屏事件

单击 -
单击事件监听器
button.setOnClickListener(new View.OnClickListener() {}
长按
button.setOnLongClickListener(new View.OnLongClickListener() {}
触摸
MontionEvent 保存触摸坐标、时间等
跟随鼠标移动的图片
单击

 public boolean onTouch(View v, MotionEvent event) {
                //功能代码
                return false; // false为单击事件
            )
            }

手势检测
onDown 按下
onFling 拖过
onLongPress 长按
onSingleTapUp 轻击
onScroll
onShowPress
↓ 用onFling做滑动效果

// 也可以单独弄一个类创建 OnGestureListener
public class MainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener {
    Animation[] animations = new Animation[4];
    final int distance = 50;
    private int[] images = new int[]{R.drawable.i1,R.drawable.i2,R.drawable.i3,R.drawable.i4};

    GestureDetector gestureDetector;
    ViewFlipper viewFlipper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gestureDetector = new GestureDetector(MainActivity.this,this); // 这里单独的this为OnGestureListener
        viewFlipper = findViewById(R.id.flipper);
        for(int i = 1; i < images.length; i++){
            ImageView imageView = new ImageView(this);
            imageView.setImageResource(images[i]);
            viewFlipper.addView(imageView);
        }
        animations[0] = AnimationUtils.loadAnimation(this, R.anim.slide_in_left);
        animations[1] = AnimationUtils.loadAnimation(this, R.anim.slide_in_right);
        animations[2] = AnimationUtils.loadAnimation(this, R.anim.slide_out_left);
        animations[3] = AnimationUtils.loadAnimation(this, R.anim.slide_out_right);

    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if(e1.getX() - e2.getX() < distance){
            viewFlipper.setInAnimation(animations[0]);
            viewFlipper.setOutAnimation(animations[2]);
            viewFlipper.showNext();
            return true;
        }else if (e1.getX() - e2.getX() > distance){
            viewFlipper.setInAnimation(animations[1]);
            viewFlipper.setOutAnimation(animations[3]);
            viewFlipper.showPrevious();
            return true;
        }
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }
}

后续的数据存储、handler、service、mvvn等等内容将会结合具体代码分析。

上一篇:抽象工厂模式 (AbstractFactory)


下一篇:SpringMVC从入门到精通