(5)数据存储

5.1 数据存储方式

Android平台提供五种存储方式:

  • 文件存储
  • SharedPreferences存储:存储一些简单的配置信息的一种机制,采用XML格式将数据存储到设备中,通常用于存储配置信息,如用户名密码等
  • SQLite数据库存储:一个轻量级数据库,运算速度快,占用内存小,支持基本SQL语法,一般作为复杂数据的存储引擎,可以存储用户信息等
  • ContentProvider:是Android四大组件之一,主要用于应用程序之间的数据交换,可以将自己的数据共享给其他的应用程序使用
  • 网络存储:网络存储需要将Android网络数据包打交道,将数据存储在服务器上,通过网络存储空间来存储获取信息

5.2 文件存储

文件存储与Java中的文件存储类似,通过I/O流的形式把数据直接存储到文件中

5.2.1 将数据存入到文件中

数据存入到文件中,有两种存储方式:内部存储和外部存储

内部存储

内部存储是将应用程序的数据以文件的形式存储到应用程序中(路径默认在data/data/),此时存储的文件会被所在的应用程序私有化,其他软件想要操作本应用程序中的文件,则需要申请权限,当创建的应用程序被卸载的时候,这里的数据也会随之被清除

实例代码如下:

FileOutputStream fos = openFileOutput(String name,int mode);//输出到文件
FileInputStream fis = openFileInput(String string);//读取文件

mode代表文件的操作模式:

  • MODE_PRIVATE:只能被应用程序读写

  • MODE_APPEND:该文件的内容可以追加

  • MODE_WORLD_READABLE:该文件的内容可以被其他程序读

  • MODE_WORLD_WRITEABLE:改文件的内容可以被其他程序写

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String filename = "data.txt";
        String content = "hello world";
        FileOutputStream fos =null;
        try {
            fos = openFileOutput(filename, Context.MODE_PRIVATE);//打开
            fos.write(content.getBytes());//写入
            Toast.makeText(MainActivity.this,"yes",Toast.LENGTH_LONG).show();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fos!=null)
                    fos.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}
外部存储

顾名思义存储到外部设备上,例如SD卡或者设备内嵌的存储卡,外部存储可以被其他应用程序读取,所以这种方式并不安全

因为外部设备可以会被移除,所以要先确认外部设备是否可用,当外部设备具有读写权限的时候,就可以通过FileOutputStream,FileInputStream来读写文件

实例代码

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String state = Environment.getExternalStorageState();
        if(state.equals(Environment.MEDIA_MOUNTED))
        {
            File SDPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);//获取到downloads路径,此方法在新版本中似乎被弃用
            File path = Environment.getDataDirectory();
            File file = new File(SDPath,"data.txt");
            String data = "hello world";
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(file);
                fos.write(data.getBytes());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    if(fos!=null)
                    {
                        fos.close();
                    }
                }catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}
Screenshot_20220412-232216_Google_文件极客

5.2.2 从文件中读取数据

读取内部存储中的数据

woc,是不是那些毒瘤那么大是不是因为把数据存到了这个地方,导致删都无法删除,这里的文件通过简单的方法是读取不了的

实例代码

//前提是已经在内部存储区域创建好了文件
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String content = "";
        FileInputStream fis =null;
        try {
            fis = openFileInput("data.txt");
            byte[] buffer = new byte[fis.available()];//创建缓冲区,获取文件的长度,数组的大小
            fis.read(buffer);//读取到buffer
            content = new String(buffer);//转为String
        }catch (Exception e)
        {
            e.printStackTrace();
        }finally {
            try {
                if(fis!=null)
                {
                    fis.close();
                }
            }catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        Toast.makeText(MainActivity.this,content,Toast.LENGTH_LONG).show();//输出
    }
}
//最后输出结果为hello world
读取外部存储文件中的数据

实例代码

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        File SDPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
        File file = new File(SDPath,"data.txt");
        FileInputStream fis = null;
        BufferedReader br =null;
        String data = "";
        try {
            fis = new FileInputStream(file);
            br = new BufferedReader(new InputStreamReader(fis));
            data = br.readLine();
        }catch (Exception e)
        {
            e.printStackTrace();
        }finally {
            try {
                if(br!=null)
                br.close();
            }catch (IOException e)
            {
                e.printStackTrace();
            }
            try {
                if(fis!=null)
                    fis.close();
            }catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        Toast.makeText(MainActivity.this,data,Toast.LENGTH_LONG).show();
    }
}
申请SD卡读取权限

为了保证应用程序的安全性,Android规定,当程序访问一些关键信息的时候,必须申请权限,根据Android SDK版本的不同,权限的申请分为两种方式,分别为静态申请权限和动态申请权限

  1. 静态申请(Android SDK 6.0以下)

    在清单文件中加入

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
  2. 动态申请Android SDK 6.0以上)

    6.0以后权限分为正常权限和危险权限(包括:位置,日历,相机,联系人,存储卡,麦克风,电话,短信)

    申请正常权限与静态权限相同,申请危险权限的时候除了需要在清单文件中申请,还需要再代码中静态申请

    ActivityCompat.requestPermissions(MainActivity.this,new String[]{"android.permission.WRITE_EXTERNAL_STORAGE"},1);
    
  3. 当用户单击申请权限的提示框的允许的时候,程序会回调执行onRequestPermissonsResult()方法

        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            if(requestCode==1)
            {
                for(int i=0;i<permissions.length;i++)
                {
                    if(permissions[i].equals("android.permission.WRITE_EXTERNAL_STORAGE")&&grantResults[i]== PackageManager.PERMISSION_GRANTED)
                    {
                        Toast.makeText(this,"申请成功",Toast.LENGTH_LONG).show();
                    }
                    else
                    {
                        Toast.makeText(this,"申请失败",Toast.LENGTH_LONG).show();
                    }
                }
            }
        }
    

5.3 SharedPreferences存储

这种存储方式相对简单,主要用于存储账号和密码等简单信息,采用键值对的形式进行存储

示例代码

SharedPreferences sp = getSharedPreferences("data",MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();//获取编辑器,data代表文件名
editor.putString("name","张三");//存储String类型数据
editor.putInt("age",18);//存储int类型数据
editor.commit();//提交数据,必须执行此操作,否则改动不起作用
SharedPreferences sp1 = getSharedPreferences("data",MODE_PRIVATE);
String data = sp.getString("name","未找到数据");//第一个参数代表key第二个参数代表缺省值,不存在key的时候就返回缺省值
editor.remove("name");//删除key=name的数据
editor.clear();//删除所有数据

5.4 SQLite数据库存储

SQLite可以存储大量数据,并且可以对数据进行管理和维护

5.4.1 SQLite数据库的创建

创建SQLite数据库只需要创建一个继承SQLiteOpenHelper类的子类,重写onCreat()方法和onUpgrade()方法

示例代码

class MyHelper extends SQLiteOpenHelper
{
    public MyHelper(Context context)//必须调用父类的构造方法
    {
        super(context,"itcast.db",null,2);
    }
    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL("CREATE TABLE information(_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20),price INTEGER)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
}

调用父类的构造方法的时候,传入的参数分别是:上下文对象,数据库名称,游标工厂(通常是null)数据库版本

重写的onCreate()方法在创建的时候调用,通常用于初始化数据库,重写的onUpgrade()方法在数据库版本号升级的时候调用

5.4.2 SQLite数据库的基本操作

新增数据

以数据库,itcast的表information为例

示例代码

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyHelper helper = new MyHelper(this);
        SQLiteDatabase db = helper.getWritableDatabase();//获取读写对象
        ContentValues contentValues = new ContentValues();//可以存储键值对
        contentValues.put("name","张三");//数据传入
        contentValues.put("price","200");
        long id = db.insert("information",null,contentValues);//插入数据到数据据中
        db.close();//关闭数据库
    }
}

需要注意的是,使用完SQLiteDatabase对象后一定要调用close()方法关闭与数据库的连接,否则数据库的连接会一直存在,不断消耗资源,当内存不足的时候就会获取不到SQLiteDatabase对象,并且会报出数据库未关闭的异常

删除数据
SQLiteDatabase db = helper.getWritableDatabase();//获取读写对象
int num = db.delete("information","_id=?",new String[]{id+""});
db.close();
修改数据
SQLiteDatabase db = helper.getWritableDatabase();//获取读写对象
ContentValues contentValues = new ContentValues();//可以存储键值对
value.put("price",price);
int number = dp.update("information",values,"name =?",new String[]{name});
db.close();

update( )的参数:第一个参数代表数据库表的名称,第二个参数表示新数据,第三个参数表示修改的数据的查找条件,第四个参数表示查找条件的参数

查询数据
public void find(int id)
{
    MyHelper helper = new MyHelper(MainActivity.this);
    SQLiteDatabase db = helper.getReadableDatabase();
    Cursor cursor = db.query("information",null,"_id=?",new String[]{id+""},null,null,null);
    if(cursor.getCount()!=0)//当数据数量不等于0的时候,进入读取循环
    {
        while(cursor.moveToNext())
        {
            @SuppressLint("Range") String _id = cursor.getString(cursor.getColumnIndex("_id"));
            @SuppressLint("Range") String name = cursor.getString(cursor.getColumnIndex("name"));
            @SuppressLint("Range") String price = cursor.getString(cursor.getColumnIndex("price"));
        }
    }
        cursor.close();//关闭Cursor(游标)对象,非常必要,原因与数据库连接的差不多
        db.close();
}

query()的七个参数:

  1. 数据库表的名称
  2. 查询的列名
  3. 接受查询条件的子句
  4. 接受查询子句对应的条件值
  5. 表示分组方式
  6. 接受having条件(定义组的过滤器)
  7. 表示排序方式
使用SQL语句对数据库进行操作

在使用SQLite数据库的时候除了上述方法,还可以使用execSQL( )方法通过SQL语句进行操作,示例代码如下

db.execSQL("insert into information (name ,price) value (?,?)",new Object[]{name,price});//增加
db.execSQL("delete from information where price =?");//删除
db.execSQL("update information set name=? where price =?",new Object[]{name,price});//修改
Cursor cursor = sb.rawQuery("select * from information whrer name =?",new String[]{name});//查询,采用此方法会返回一个结果集

5.4.3 SQLite数据库中的事务

数据库事务是一个对数据库执行工作单元,是针对数据库的一组操作,他可以由一条或者多条SQL语句组成,事务是以逻辑顺序完成的工作单位或序列,可以由用户手动操作完成,也可以由某种数据库程序自动完成

事务的操作比较严格,他必须包括ACID,ACID是指数据库事务正确执行的的四个基本要素的缩写,这四个要素分别是

  • 原子性:表示事务是一个不可以再分割的工作单位,事务中的操作要么全部成功,要么全部回滚
  • 一致性:表示事务开始之前和结束之后,数据库的完整性没有被破坏,也就是说数据库事务不能破坏关系数据库的完整性及业务逻辑上的一致性
  • 隔离性:表示并发的事务时相互隔离的,也就是一个事务内部操作都必须封装起来,不被其他事务影响到
  • 持久性:表示事务一旦提交,该事务对数据做的更改便持久保存在数据库中,并不会被回滚,即使出现了断电等事故,也不会影响数据库中的数据

实例代码

PersonSQLiteOpenHelper = helper = new PersonSQLiteOpenHelper(getApplication());
SQLiteDatabase db = helper.getReadableDatabase();
db.beginTransaction();
try
{
    db.execSQL("update person set accont = accont - 1000 where name =?",new Object[]{"张三"});//转出1000
    db.execSQL("update information set accont = accont + 1000 where name =?",new Object[]{"王五"});//收入1000
    db.setTransactionSucessful();//设置数据库事务处理成功
}catch(Exception e)
{
    Log.i("事务处理失败",e.toString())
}finally
{
    db.endTransaction();//关闭事务
    db.close();
}

需要注意的时:事务操作后一定要关闭事务,如果由事务成功执行的标志,则提交数据,否则数据回滚,最后关闭事务

5.4.4 实战演练-密码管理器

MainActivity.java

bug:mainactivity登录界面未完善

package cn.itcast.myapplication10;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;


public class MainActivity extends AppCompatActivity {
    Button btn_login;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_login = findViewById(R.id.btn_login);
        btn_login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(MainActivity.this,PWD.class));
            }
        });
    }
}

PWD.java

package cn.itcast.myapplication10;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Vector;

public class PWD extends AppCompatActivity implements View.OnClickListener{
    Myhelper myhelper;
    private Button mbtn_ser;
    private Button mbtn_re;
    private Button mbtn_add;
    private Button mbtn_delete;
    private Button mbtn_clear;
    private Button mbtn_display;
    private EditText med_des;
    private EditText med_acc;
    private EditText med_pwd;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pwd);
        myhelper = new Myhelper(this);
        Init();
    }
    
    void Init()
    {
        mbtn_ser = findViewById(R.id.btn_search);
        mbtn_add = findViewById(R.id.push);
        mbtn_re = findViewById(R.id.btn_re);
        mbtn_delete = findViewById(R.id.btn_delete);
        mbtn_clear = findViewById(R.id.btn_clear);
        mbtn_display = findViewById(R.id.btn_display);
        med_des = findViewById(R.id.ed_des);
        med_acc = findViewById(R.id.ed_accont);
        med_pwd = findViewById(R.id.ed_pwdd);
        mbtn_ser.setOnClickListener(this);
        mbtn_add.setOnClickListener(this);
        mbtn_re.setOnClickListener(this);
        mbtn_delete.setOnClickListener(this);
        mbtn_clear.setOnClickListener(this);
        mbtn_display.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        String describtion,account,password;
        SQLiteDatabase db;
        ContentValues values;
        switch (view.getId())
        {
            case R.id.btn_search://查询
                describtion = med_des.getText().toString();
                med_acc.setText("");
                med_pwd.setText("");
                if(TextUtils.isEmpty(describtion))
                {
                    Toast.makeText(PWD.this,"填写描述开始查询",Toast.LENGTH_LONG).show();
                    return;
                }
                db = myhelper.getReadableDatabase();
                Cursor cursor = db.query("information",null,null,null,null,null,null);
                if(cursor.getCount()==0) {
                    Toast.makeText(PWD.this, "表为空", Toast.LENGTH_LONG).show();
                    db.close();
                    cursor.close();
                    return;
                }
                else
                {
                    cursor.moveToFirst();
                    do{
                        if(cursor.getString(3).equals(describtion))
                        {
                            med_des.setText(cursor.getString(3));
                            med_acc.setText(cursor.getString(1));
                            med_pwd.setText(cursor.getString(2));
                        }
                    }while (cursor.moveToNext());
                }
                if(TextUtils.isEmpty(med_pwd.getText().toString())) {
                    Toast.makeText(PWD.this, "未找到数据", Toast.LENGTH_LONG).show();
                    med_des.setText("");
                }
                cursor.close();
                db.close();
                break;
            case R.id.push://插入
                describtion = med_des.getText().toString();
                account = med_acc.getText().toString();
                password = med_pwd.getText().toString();
                if(TextUtils.isEmpty(describtion)||TextUtils.isEmpty(account)||TextUtils.isEmpty(password)) {
                    Toast.makeText(PWD.this, "上面信息必须填完", Toast.LENGTH_LONG).show();
                    return;
                }
                db = myhelper.getReadableDatabase();
                Cursor cursor1 = db.query("information",null,null,null,null,null,null);
                cursor1.moveToFirst();
                if(cursor1.getCount()!=0) {
                    do {
                        if (cursor1.getString(3).equals(describtion))//检测重复
                        {
                            Toast.makeText(PWD.this, "该描述对应条目已存在", Toast.LENGTH_LONG).show();
                            med_des.setText("");
                            med_acc.setText("");
                            med_pwd.setText("");
                            cursor1.close();
                            db.close();
                            return;
                        }
                    } while (cursor1.moveToNext());
                }
                db = myhelper.getWritableDatabase();
                values = new ContentValues();
                values.put("describe",describtion);
                values.put("account",account);
                values.put("pwdd",password);
                db.insert("information",null,values);
                Toast.makeText(PWD.this,"信息已添加",Toast.LENGTH_LONG).show();
                med_des.setText("");
                med_acc.setText("");
                med_pwd.setText("");
                cursor1.close();
                db.close();
                break;
            case R.id.btn_re://修改
                boolean flag=false;//是否存在条目
                describtion = med_des.getText().toString();
                account = med_acc.getText().toString();
                password = med_pwd.getText().toString();
                if(TextUtils.isEmpty(describtion)||TextUtils.isEmpty(account)||TextUtils.isEmpty(password)) {
                    Toast.makeText(PWD.this, "上面信息必须填完", Toast.LENGTH_LONG).show();
                    return;
                }
                db= myhelper.getWritableDatabase();
                values = new ContentValues();
                Cursor cursor2 = db.query("information",null,null,null,null,null,null);
                cursor2.moveToFirst();
                do{
                    if(cursor2.getString(3).equals(describtion))//检测重复
                    {
                        flag=true;
                    }
                }while (cursor2.moveToNext());
                if(!flag)
                {
                    Toast.makeText(PWD.this, "没有找到该描述对应条目", Toast.LENGTH_LONG).show();
                    db.close();
                    cursor2.close();
                    return;
                }
                values.put("account",account);
                values.put("pwdd",password);
                db.update("information",values,"describe=?",new String[]{describtion});
                Toast.makeText(PWD.this, "信息已修改", Toast.LENGTH_LONG).show();
                db.close();
                cursor2.close();
                break;
            case R.id.btn_delete://删除
                boolean flag1=false;
                describtion = med_des.getText().toString();
                if(TextUtils.isEmpty(describtion))
                {
                    Toast.makeText(PWD.this, "请填描述以删除", Toast.LENGTH_LONG).show();
                    return;
                }
                db = myhelper.getWritableDatabase();
                Cursor cursor3 = db.query("information",null,null,null,null,null,null);
                cursor3.moveToFirst();
                do{
                    if(cursor3.getString(3).equals(describtion))
                    {
                        flag1=true;
                    }
                }while (cursor3.moveToNext());
                if(!flag1)
                {
                    Toast.makeText(PWD.this, "没有找到该描述对应条目", Toast.LENGTH_SHORT).show();
                    db.close();
                    cursor3.close();
                    return;
                }
                db.delete("information","describe=?",new String[]{describtion});
                Toast.makeText(PWD.this, "已删除", Toast.LENGTH_LONG).show();
                db.close();
                cursor3.close();
                break;
            case R.id.btn_clear:
                med_des.setText("");
                med_acc.setText("");
                med_pwd.setText("");
                break;
            case R.id.btn_display:
                Intent intent = new Intent();
                intent.setClass(PWD.this,Display.class);
                db= myhelper.getWritableDatabase();
                Cursor cursor4 = db.query("information",null,null,null,null,null,null);
                ArrayList<String> data=new ArrayList<>();
                cursor4.moveToFirst();
                if(cursor4.getCount()!=0)
                do {
                    StringBuffer temp = new StringBuffer();

                    temp.append(cursor4.getString(3)).append('\n');
                    temp.append(cursor4.getString(1)).append('\n');
                    temp.append(cursor4.getString(2)).append('\n');
                    data.add(new String(temp));
                }while(cursor4.moveToNext());
                intent.putExtra("database",data);//传出数据
                startActivity(intent);
                db.close();
                cursor4.close();
                break;
            default:
                break;
        }
    }
}
class Myhelper extends SQLiteOpenHelper
{
    Myhelper(Context context)
    {
        super(context,"ittcast.db",null,1);
    }
    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL("CREATE TABLE information(_id INTEGER PRIMARY KEY AUTOINCREMENT ,account VARCHAR(20),pwdd VARCHAR(20),describe VAECHAR(20))");//创建数据库
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
}

Display.java

package cn.itcast.myapplication10;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Vector;

public class Display extends AppCompatActivity {
    private TextView view_display;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_display);
        view_display = findViewById(R.id.dis);
        Intent intent = getIntent();
        ArrayList<String> temp = new ArrayList<>();
        temp = (ArrayList<String>)intent.getSerializableExtra("database");
        for(int i=0;i<temp.size();i++)
        {
            view_display.append("id="+(i+1)+":"+'\n');
            view_display.append(temp.get(i));
        }
    }
}

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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="20dp"
    android:orientation="vertical"
    tools:context=".PWD">
    <TextView
        android:layout_gravity="center"
        android:layout_marginTop="50dp"
        android:id="@+id/textlogin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="少侠请登录"
        android:textSize="40dp"
        android:textColor="#000000"
        android:layout_marginBottom="50dp"/>
    <EditText
        android:id="@+id/ed_acc"
        android:layout_margin="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="账户名:"/>
    <EditText
        android:id="@+id/ed_pwd"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="密码:"
        android:inputType="textPassword" />

    <Button
        android:layout_marginTop="50dp"
        android:layout_gravity="center"
        android:id="@+id/btn_login"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="登录"/>
    <Button
        android:layout_marginTop="20dp"
        android:layout_gravity="center"
        android:id="@+id/btn_forget"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="忘记密码"/>

</LinearLayout>

activity_pwd.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="40dp"
    android:orientation="vertical"
    tools:context=".PWD">
    <TextView
        android:layout_gravity="center"
        android:layout_marginTop="30dp"
        android:id="@+id/textlogin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="(●'◡'●)"
        android:textSize="40dp"
        android:textColor="	#FF7F50"
        android:layout_marginBottom="50dp"/>
    <EditText
        android:id="@+id/ed_des"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="描述信息:"/>
    <EditText
        android:id="@+id/ed_accont"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="账户名:"/>
    <EditText
        android:id="@+id/ed_pwdd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="password:"/>
    <Button
        android:layout_marginTop="30dp"
        android:layout_gravity="center"
        android:id="@+id/btn_search"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="查询"/>
    <Button
        android:layout_marginTop="10dp"
        android:layout_gravity="center"
        android:id="@+id/push"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="录入"/>
    <Button
        android:layout_marginTop="10dp"
        android:layout_gravity="center"
        android:id="@+id/btn_re"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="修改"/>
    <Button
        android:layout_marginTop="10dp"
        android:layout_gravity="center"
        android:id="@+id/btn_delete"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="删除"/>
    <Button
        android:layout_marginTop="10dp"
        android:layout_gravity="center"
        android:id="@+id/btn_clear"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="清除"/>
    <Button
        android:layout_marginTop="10dp"
        android:layout_gravity="center"
        android:id="@+id/btn_display"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="全部显示"/>
</LinearLayout>

activity_display.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Display">
    <TextView
        android:id="@+id/dis"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

实例图片

image-20220417225059859

image-20220417225125887

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/* * 这个类主要包括五个点击事件,分别为 * 1,ListView的长按点击事件,用来AlertDialog来判断是否删除数据。 * 2,ListView的点击事件,跳转到第二个界面,用来修改数据 * 4,menu里的退出事件,用来退出程序 * 5,menu里的新建事件,用来新建便签 * 6,对返回按钮监听退出程序 */ public class MainActivity extends Activity { // 定义帮助类 private MyOpenHelper notesDB; // 定义数据库类 private SQLiteDatabase dbReader;// 读取 // 定义组件 private ListView lv; private Button bt; private TextView tvBody; private TextView tvTitle; // 数据库表名称 private static final String TABLE_NAME = "data"; // 定义选项菜单 private static final int DB_ISNERT = 0x11; private static final int EXIT = 0x12; // 定义上下文菜单 private static final int DB_DELETE = 0x22; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bt = (Button) findViewById(R.id.button1); // 实例化数据库对象 notesDB = new MyOpenHelper(this); // 创建数据库 dbReader = notesDB.getWritableDatabase(); // 取出组件 lv = (ListView) findViewById(R.id.listView1); // 设置监听 // 注册ListView上下文菜单 this.registerForContextMenu(lv); // 一打开软件就进行数据库查询把数据库中的内容查询显示 queryData(); // 短按时跳到第二个界面进行查看,修改 lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub Cursor c = dbReader.query(TABLE_NAME, null, null, null, null, null, null); c.moveToPosition(position);// 移动光标到一个绝对的位置 Intent i = new Intent(MainActivity.this, SecondAtivity.class); String s = String.valueOf(id); i.putExtra(SecondAtivity.mRowId, s); i.putExtra(SecondAtivity.KEY_BODY, c.getString(c.getColumnIndex(SecondAtivity.KEY_BODY))); i.putExtra(SecondAtivity.KEY_TITLE, c.getString(c.getColumnIndex(SecondAtivity.KEY_TITLE))); // 把数据库中的内容传到SecondAtivity startActivityForResult(i, 1); } }); } /** * 填充ListView */ public void queryData() { // 游标 查询数据库 Cursor cursor = dbReader.query(TABLE_NAME, null, null, null, nul

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值