Android个人笔记

Android系统四层架构

image-20200705214742824

Android四大组件

image-20200705214839526

常用布局管理器及继承关系

image-20200705215207417

  • 常用布局管理器
    • LinearLayout(线性布局)
    • RelativeLayout(相对布局)
    • TableLayout(相对布局)
    • AbsoluteLayout(绝对布局)
    • TableLayout(表格布局)
    • GridLayout(网格布局)

Activity生命周期

image-20200705215748310

Handler

Handler类的作用包括:在新启动的线程中发送消息和在主线程中获取和处理消息

image-20200705220855145

ListView的使用

image-20200705221321304

image-20200705221454067

image-20200705221535119

菜单使用时需回调的方法

image-20200705221655052

编程

1、布局管理器的课上讲解练习

线性布局

  • LinearLayout:线性布局,子控件的排列顺序是在水平方向或竖直方向一个挨着一个排列
  • orientation:指定排列方向
  • vertical:在竖直方向排列
  • horizontal:水平方向排列
  • weightSum:指定总比重
  • layout_weight:指定子控件的占的比重
<?xml version="1.0" encoding="utf-8"?>
<!--LinearLayout:线性布局,子控件的排列顺序是在水平方向或竖直方向一个挨着一个排列
orientation:指定排列方向,vertical:在竖直方向排列  horizontal:水平方向排列
weightSum:指定总比重
layout_weight:指定子控件的占的比重-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="20">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="2"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="3"/>

</LinearLayout>

相对布局

  • RelativeLayout:相对布局,子控件的位置是由父控件或兄弟控件的相对位置决定
  • 根据父控件的相对位置的属性:
    • layout_centerInParent:在容器的正中间
    • layout_centerVertical:在容器的竖直方向的中间
    • layout_centerHorizontal:在水平方向的中间
    • layout_alignParentLeft:和父控件的左边框对齐
    • layout_alignParentRight:和父控件的右边框对齐
    • layout_alignParentTop:和父控件的上边框对齐
    • layout_alignParentBottom:和父控件的下边框对齐
  • 根据兄弟控件的相对位置的属性:
    • layout_toLeftOf:在某个兄弟控件的左边
    • layout_toRightOf:右边
    • layout_above:上边
    • layout_below:下边
    • layout_alignLeft:和兄弟控件左边框对齐
    • layout_alignRight:有边框对齐
    • layout_alignTop:上边框对齐
    • layout_alignBottom:下边框对齐
<?xml version="1.0" encoding="utf-8"?>
<!--RelativeLayout:相对布局,子控件的位置是由父控件或兄弟控件的相对位置决定
根据父控件的相对位置的属性:
layout_centerInParent:在容器的正中间
layout_centerVertical:在容器的竖直方向的中间
layout_centerHorizontal:在水平方向的中间
layout_alignParentLeft:和父控件的左边框对齐
layout_alignParentRight:和父控件的右边框对齐
layout_alignParentTop:和父控件的上边框对齐
layout_alignParentBottom:和父控件的下边框对齐

根据兄弟控件的相对位置的属性:
layout_toLeftOf:在某个兄弟控件的左边
layout_toRightOf:右边
layout_above:上边
layout_below:下边
layout_alignLeft:和兄弟控件左边框对齐
layout_alignRight:有边框对齐
layout_alignTop:上边框对齐
layout_alignBottom:下边框对齐
-->
<RelativeLayout 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/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text=""/>

    <Button
        android:layout_above="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/btn"
        android:text=""/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btn"
        android:layout_alignLeft="@+id/btn"
        android:text=""/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@+id/btn"
        android:layout_alignTop="@+id/btn"
        android:text="西"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/btn"
        android:layout_alignTop="@+id/btn"
        android:text=""/>

</RelativeLayout>

绝对布局

  • **AbsoluteLayout:(不建议使用,适配效果差)绝对布局,控件的位置是根据绝对坐标点决定,坐标原点是左上角
    • layout_x:指定控件x轴坐标
    • layout_y:指定y轴坐标
<?xml version="1.0" encoding="utf-8"?>
<!--AbsoluteLayout:(不建议使用,适配效果差)绝对布局,控件的位置是根据绝对坐标点决定,坐标原点是左上角
layout_x:指定控件x轴坐标
layout_y:指定y轴坐标-->
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="100dp"
        android:layout_y="100dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</AbsoluteLayout>

网格布局

  • GridLayout:网格布局
    • rowCount:指定一共有多少行
    • columnCount:指定一共有多少列
    • layout_row:指定控件在多少行
    • layout_column:指定在多少列
    • layout_columnSpan:横跨多少列,需要同时设置layout_gravity="fill"
    • layout_rowSpan:竖跨多少行,需要同时设置layout_gravity="fill"
<?xml version="1.0" encoding="utf-8"?>
<!--GridLayout:网格布局
rowCount:指定一共有多少行
columnCount:指定一共有多少列
layout_row:指定控件在多少行
layout_column:指定在多少列
layout_columnSpan:横跨多少列,需要同时设置layout_gravity="fill"
layout_rowSpan:竖跨多少行,需要同时设置layout_gravity="fill"-->
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:rowCount="5"
    android:columnCount="5">

    <Button />
    <Button
        android:layout_row="1"
        android:layout_column="2"
        android:layout_columnSpan="2"
        android:layout_rowSpan="2"
        android:layout_gravity="fill"/>


    <Button/>   <Button/>   <Button/>
    <Button/>   <Button/>  <Button/>  <Button/>  <Button/>
    <Button/>

</GridLayout>

表格布局

  • 表格布局,有多少行就添加几个TableRow
<?xml version="1.0" encoding="utf-8"?>
<!--TableLayout:表格布局,有多少行就添加几个TableRow-->
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TableRow>
        <Button />   <Button/> <Button/>
    </TableRow>

    <TableRow>
        <Button/>   <Button/> <Button/>  <Button/>
    </TableRow>

    <TableRow>
        <Button/>   <Button/>
    </TableRow>



</TableLayout>

帧布局

  • layout_gravity:控制控件的对齐位置
<?xml version="1.0" encoding="utf-8"?>
<!--FrameLayout:帧布局,每一个子控件是一帧
layout_gravity:控制控件的对齐位置-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"/>



</FrameLayout>

2、通过ContentReceiver的使用

BroadcaseReceiver

BroadcastReceiver是广播接收器,用于接收系统和应用中的广播
BroadcastReceiver是一种对广播进行过滤接收并响应的组件
自身并不提供用户图形界面
本质上就是一个全局监听器,用于监听系统全局的广播消息

实现广播和接收Intent的步骤

注册BroadCaseReceiver广播接收器

image-20200617191407083

上面的方式已经过时,不安全,现在都是动态注册

  • 动态注册

    image-20200617193414370

image-20200617193730387

3、使用IO流进行文件读写

IO读写

package com.example.asyncdemo;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

 /*//访问外部存储中公有目录下的文件,都需要添加读或写文件的权限
        // 获取外部存储根目录
        Environment.getExternalStorageDirectory();  //
        //获取9大公有目录
        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);

        *//*获取的外部存储中私有目录 不需要权限*//*
        getExternalCacheDir();   //android/data/com.example.asyncdemo/cache
        getExternalFilesDir("a.txt");    //android/data/com.example.asyncdemo/file/a.txt

        *//*获取内部存储中的私有目录,不需要权限
        MODE_PRIVATE:覆盖的模式,写入文件的内容会替换之前的内容
        MODE_APPEND:追加的模式*//*
        getDir("a.txt",MODE_APPEND);  //data/data/com.example.asyncdemo/a.txt
        getCacheDir();     //data/data/com.example.asyncdemo/cache
        getFilesDir();    //data/data/com.example.asyncdemo/files
        try {
            InputStream is = openFileInput("a.txt");  //data/data/com.example.asyncdemo/file/a.txt  文件对应的输入流
            OutputStream os = openFileOutput("a.txt",MODE_PRIVATE);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }*/
public class MainActivity extends AppCompatActivity {
    ProgressBar pb;

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pb = findViewById(R.id.pb);

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
         //如果没有写文件的权限,进行申请
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},101);
        }else {  //如果有权限,直接写文件
            writeE();
        }

        /*读取内部存储中/files目录下的文件,不需要读写的权限*/
//        try {  //写文件
//            OutputStream outputStream = openFileOutput("a.txt",MODE_APPEND);
//            outputStream.write("你好".getBytes());
//            outputStream.close();
//
//            /*读取文件*/
//            InputStream is = openFileInput("a.txt");
//            byte[] bytes = new byte[1024];
//            while (is.read(bytes) != -1){
//                Toast.makeText(getApplicationContext(),bytes.toString(),Toast.LENGTH_SHORT).show();
//            }
//
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//
//        MyTask myTask = new MyTask();
//        myTask.execute();  //执行异步任务
    }

    /*动态权限申请结果的回调*/
     @Override
     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
         super.onRequestPermissionsResult(requestCode, permissions, grantResults);
         if (requestCode == 101 && grantResults[0] == PackageManager.PERMISSION_GRANTED){   //表示用户选择了运行授予权限
             writeE();
         }else {
             finish();
         }
     }

     /*该方法用于读取共有目录的文件*/
    public void writeE(){
        String path = Environment.getExternalStorageDirectory()+ "/my/a.txt";
        File file = new File(path);
        if(!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                FileOutputStream fos = new FileOutputStream(file);
                fos.write("你很好".getBytes());
                fos.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }

    class MyTask extends AsyncTask<Void,Integer,String>{

        /*耗时操作执行之前调用,进行一些初始化操作*/
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        /*此方法用于执行耗时操作,此方法运行在子线程中*/
        @SuppressLint("WrongThread")
        @Override
        protected String doInBackground(Void... voids) {
            for(int a = 0;a<100;a++){
                try {
                    Thread.sleep(100);
                    onProgressUpdate(a+1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return "下载任务执行完成";
        }

        /*该方法进行实时更新UI,此方法在主进线中执行*/
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            pb.setProgress(values[0]);
        }

        /*耗时操作执行完成后回调该方法,主线程中执行*/
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            /*耗时操作执行完之后设置进度条不可见*/
            pb.setVisibility(View.GONE);
            Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show();
        }
    }
}

4、SQLiteOpenHelper的使用

SQLite

数据库文件存储在内部文件,data/该应用文件/databases中

代码示例

  • 这种方式尽量不用
package com.qst.sqlitedemo;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.widget.SimpleCursorAdapter;

public class MainActivity extends AppCompatActivity {
    SQLiteDatabase db;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//
        PenpleDao dao = new PenpleDao();
        dao.insert(this);

        //打开一个数据库对象,如果不存在则新建该数据库,该数据库默认保存在内部存储
        db = openOrCreateDatabase("my.db",MODE_PRIVATE,null);

        try{
            //execSQL执行sql语句,创建一张表
//            db.execSQL("CREATE table student(id integer primary key,age integer,name text)");

            //向表中插入一条数据
            db.execSQL("INSERT into student(id,age,name)values(1,25,'zhangsan')");

            //通过insert方法插入一条数据,insert返回值是插入行的rowid,如果返回-1表示插入失败
            ContentValues cv = new ContentValues();
            cv.put("id",3);
            cv.put("age",20);
            cv.put("name","lisi");
            db.insert("student",null,cv);
        }catch(Exception e){
            e.printStackTrace();
        }



        //删除数据操作
//        db.execSQL("delete from student where id=1");
//        db.delete("student","name=?",new String[]{"lisi"});  //返回值表示多少行数据被影响了
//
//        //修改数据
//        db.execSQL("update student set age=10 where id=2");
//
//        ContentValues cv2 = new ContentValues();
//        cv2.put("name","wangwu");
//        db.update("student",cv2,"name=?",new String[]{"lisi"}); //返回值表示多少行数据被影响了
//
//        //查询,返回结果是一个cursor游标对象,该对象类似于JDBC  ResultSet
        Cursor cursor = db.query(true,"student",new String[]{"age,name"},
                "id<?",new String[]{"10"},null,null,null,null);
        while (cursor.moveToNext()){
            Log.d("sql",cursor.getInt(0)+"");
            Log.d("sql",cursor.getString(1));
        }

        db.close();


    }
}

SQLiteOpenHelper

MyDBHelper.java 代码示例

package com.qst.sqlitedemo;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import androidx.annotation.Nullable;

/*用于获取数据库连接*/
public class MyDBHelper extends SQLiteOpenHelper {

    public MyDBHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    /*创建数据库时回调该方法,一般在该方法里执行表的创建*/
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table people(_id integer primary key autoincrement,name text,age integer,phone text)");
        db.execSQL("create table student(_id integer primary key autoincrement,name text,age integer,phone text)");
    }

    /*数据库版本更新时执行该方法*/
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

PeopleDao实例代码

package com.qst.sqlitedemo;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;

/*封装对people表的增删改查的操作*/
public class PenpleDao {

    public void insert(Context context){
        //实例化MyDBHelper对象,第二个参数:数据库的名字
        MyDBHelper myDBHelper = new MyDBHelper(context,"test.db",null,1);
        //通过myDBHelper获取一个数据库对象(数据库连接)
        SQLiteDatabase db = myDBHelper.getWritableDatabase();

        ContentValues cv = new ContentValues();
        cv.put("age",20);
        cv.put("name","lisi");
        db.insert("people","",cv);

        db.close();
        myDBHelper.close();
    }


}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值