安卓开发——有用的网址、经典问题整理

1. 安卓adb无线连接

网址:https://www.cnblogs.com/arcsinw/p/15863513.htmlicon-default.png?t=N7T8https://www.cnblogs.com/arcsinw/p/15863513.html

2. startActivityForResult 废用 — 改为 registerForActivityResult

​ 安卓的startActivityForResult 方法废用,改为使用registerForActivityResult

 java版写法:​【Android】registerForActivityResult新的向上传递数据技术(使用java语言解释)_registerforactivityresult java-CSDN博客文章浏览阅读522次。registerForActivityResult 向上一个活动传递数据。startActivityForResult的替代方案registerForActivityResult_registerforactivityresult javahttps://blog.csdn.net/m0_72983118/article/details/131784562

2.1 只有一个调用的情况

 需求:活动A启动活动B,活动B返回时让活动A收到来自B的消息

  • startActivityForResult 方法:

A:

B:

 ​​​​​​

  • 现在的 registerForActivityResult方法:

A:

ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),new ActivityResultCallback<ActivityResult>() {@Overridepublic void onActivityResult(ActivityResult result) {//判断是否传入正确的resultif(result.getResultCode() == RESULT_OK){Intent intent = result.getData();   //获取上一个活动返回的Intent//判断上一个活动的Intent是否存在,存在则在日志中输入if(intent != null){String edit = intent.getStringExtra("input");Log.d(TAG, edit);}}}});Intent intent = new Intent(MainActivity.this, EditActivity.class);//向下传递Intent
resultLauncher.launch(intent);

B:

Intent intent = new Intent();
//给这个Intent封装value
intent.putExtra("input",et.getText().toString());
//返回活动的结果
setResult(RESULT_OK,intent);
finish();
2.2 有多个调用的情况

当我们在多个地方调用resultLauncher.launch(intent);,而且在registerForActivityResult里面需要执行的逻辑不同时需要注意一下。

上面两张图各使用了一次resultLauncher.launch(intent);,它们在registerForActivityResult里面对应的逻辑不同。

我们可以看到可以给Intent定义一个属性,比如mode,我们通过判断mode的值来决定执行哪种功能。

3. 图标 在layout文件的预览中可以看到,但是运行后没有显示?

运行后不显示图标:

这是因为图标部分用的是tools,只会在预览中显示,运行后不显示

改成app后就能在运行后也显示图标了

结果显示:

4. 数据库操作流程(CRUD、ContentValues、Cursor)

参考:【最完整】Android安卓开发-记事本(三)数据库操作与笔记显示_哔哩哔哩_bilibili【最完整】Android安卓开发-记事本(三)数据库操作与笔记显示是【最完整】Android安卓开发-记事本的第3集视频,该合集共计12集,视频收藏或关注UP主,及时了解更多相关视频内容。icon-default.png?t=N7T8https://www.bilibili.com/video/BV1m4411z7C8?p=3&vd_source=677c497f24b8d84096d3032ada357bc4

首先我们可以看一下最终的对数据库的操作:向数据库里添加一条note数据

上面的代码执行后,会往数据库中添加一条note数据,我们一步步分解任务

4.1 首先创建note类:

note类有4个属性,再自行添加各个属性的get、set方法、toString、构造方法即可完成该实体类创建:

package com.xht.note;public class Note {private long id;private String content;private String time;private int tag;public Note() {}public Note(String content, String time, int tag) {this.content = content;this.time = time;this.tag = tag;}public long getId() {return id;}public void setId(long id) {this.id = id;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public String getTime() {return time;}public void setTime(String time) {this.time = time;}public int getTag() {return tag;}public void setTag(int tag) {this.tag = tag;}@Overridepublic String toString() {return content + "\n" + time.substring(5, 16) + " " + id;}
}

4.2 其次创建note类的数据库帮助类

        创建了一个名为 NoteDatabase 的数据库帮助类,它继承自 SQLiteOpenHelper。在 构造方法NoteDatabase 中,通过 super(context, "note", null, 1) 指定了数据库文件的名称为 "note",版本号为 1。

         onCreate() 方法和 onUpgrade() 方法是用于管理数据库的两个重要方法,其中onUpgrade() 方法。

        其中onUpgrade() 方法用于数据库升级。当应用程序更新并且新版本号高于旧版本号时,系统将调用此方法。在该方法中,可以根据不同的旧版本号执行不同的数据库升级操作,暂时没用上,先忽略这个函数。

        onCreate(SQLiteDatabase db) 方法用于创建数据库表。在调用 getWritableDatabase() 或者 getReadableDatabase() 方法(这两个方法在下一节中会使用并介绍)时,如果数据库文件不存在,就会执行。在该方法中,执行创建数据库表的 SQL 语句:通过调用 db.execSQL() 方法执行 SQL 语句来创建名为 note 的表,包括 _id、content、time 和 mode 四个列。

package com.xht.note;import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;import androidx.annotation.Nullable;public class NoteDatabase extends SQLiteOpenHelper {public static final String TABLE_NAME = "note";public static final String CONTENT = "content";public static final String ID = "_id";public static final String TIME = "time";public static final String MODE = "mode";public NoteDatabase(Context context) {super(context, "note", null, 1);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL("CREATE TABLE " + TABLE_NAME+ "("+ ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"+ CONTENT + " TEXT NOT NULL,"+ TIME + " TEXT NOT NULL,"+ MODE + " INTEGER DEFAULT 1)");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//        for(int i = oldVersion; i < newVersion; i++){
//            switch (i){
//                case 1:
//                    break;
//                case 2:
//                    updateMode(db);
//                default:
//                    break;
//            }
//        }}
}

4.3 创建CRUD(增删改查)操作类,进行数据的操作

        SQLiteDatabase db 是一个用于执行数据库操作的对象。通常情况下,它被用来执行:查询、插入、更新和删除等操作。

         SQLiteOpenHelper dbHandler 是一个用于管理数据库的辅助类对象。SQLiteOpenHelper 是一个抽象类,用于创建和管理数据库,可以在其中实现数据库的创建、升级等操作。在这里,dbHandler 可以是 NoteDatabase 类的实例,因为 NoteDatabase 类继承自 SQLiteOpenHelper。通过 dbHandler,可以获取一个可读或可写的数据库连接,并执行相应的操作。

        总的来说,这两个变量在该类中用于对数据库进行操作和管理,其中 db 用于执行具体的数据库操作,而 dbHandler 则用于管理数据库的创建和升级等操作。

        以上是CRUD 类的构造函数和两个方法:open 和 close。

         public CRUD(Context context) 是 CRUD 类的构造函数,接受一个 Context 参数。在构造函数中,它创建了一个 NoteDatabase 对象,并将其赋值给 dbHandler 成员变量。这里的 NoteDatabase 是继承自 SQLiteOpenHelper 的数据库帮助类,用于创建和管理数据库。

        public void open() 方法用于打开数据库连接。在该方法中,它通过调用 dbHandler.getWritableDatabase() 方法获取可写的数据库连接(上一节提到过这个方法,当调用该方法时,如果数据库文件还没有创建就会执行上一节的onCreate方法创建数据库),并将其赋值给 db 成员变量。这样就可以在其他方法中使用 db 对象来执行数据库操作了。

         public void close() 方法用于关闭数据库连接。在该方法中,它调用 dbHandler.close() 方法关闭数据库帮助类,从而关闭数据库连接。

        这三个方法一起用于管理数据库的打开和关闭操作,确保在需要使用数据库时可以打开连接,并在不需要使用时及时关闭连接,以避免资源泄漏和提高应用程序的性能。

4.3.1 增方法

我们看一下“增”操作,向数据库中添加新记录。

         创建一个 ContentValues 对象,用于存储要插入的数据。 使用 put() 方法将 note 对象的内容、时间和标签放入 ContentValues 对象中,使用的键分别对应数据库表中的列名。

        调用 db.insert() 方法向数据库表中插入数据,并将返回的插入行的 ID 存储在 insertId 变量中。 将插入行的 ID 设置给 note 对象的 id 属性。 返回更新后的 note 对象。

        这段代码实现了向数据库表中插入新记录,并将插入的行的 ID 设置给对应的 note 对象,然后返回更新后的 note 对象。

4.3.2 contentValues介绍

        前面的“增”方法里有contentValues,现在介绍一下:

        ContentValues 是 Android 中用于存储键值对的类,通常用于在数据库操作中存储要插入或更新的数据。 它类似于 Java 中的 Map 接口,但是它设计用于存储特定类型的键值对,而且可以轻松地与 Android 提供的数据库 API 进行交互。

         ContentValues 可以存储不同类型的数据,包括基本数据类型如字符串、整数、浮点数、长整数等。在数据库操作中,通常会使用 ContentValues 对象将要插入或更新的数据以键值对的形式放入,然后通过数据库 API 将这些数据插入到数据库表中或者更新已有的数据。

        上图代码中ContentValues 对象用于存储要插入到数据库表中的数据,其中键对应note数据库表的列名,值对应要插入的具体数据。通过调用 put() 方法,将数据放入 ContentValues 对象中,然后传递给 insert() 方法将这些数据插入到数据库表中。

4.3.3 查方法
  •  一次查一个数据:

        使用 db.query() 方法查询数据库表,指定要查询的表名、要返回的列、查询条件以及查询条件的参数。

        如果查询到结果,将光标移动到结果集的第一行,即调用 cursor.moveToFirst() 方法。 从光标中读取当前行的数据,并使用它们创建一个 Note 对象。 返回该 Note 对象。

        总的来说,这段代码实现了从数据库中查询特定 ID 的记录,并将查询到的数据转换为 Note 对象返回。

  • 一次查所有的数据

        在这段代码中,执行 Cursor cursor = db.query(...) 语句将会执行一个查询,获取包含所有note的结果集。

        然后通过 cursor.getCount() 方法获取结果集中的行数,如果结果集中有数据(行数大于0),则进入 if 语句块中。 在 if 语句块中,首先调用 cursor.moveToNext() 方法,将光标移动到结果集的第一行。因为光标初始位置是在结果集的第一行之前的“假想”位置,所以第一次调用 moveToNext() 方法将光标移到第一行数据上。

        随后进入 while 循环中,每次迭代都调用 cursor.moveToNext() 来移动光标到下一行,直到遍历完所有行。 在循环体内,通过 cursor.getLong()、cursor.getString() 和 cursor.getInt() 方法从光标当前行中提取数据,并将提取的数据设置到一个 Note 对象中。然后将该 Note 对象添加到 notes 列表中。 最后返回包含所有 Note 对象的 notes 列表。

        这段代码的目的是获取数据库中所有笔记的数据,并将其封装到 Note 对象中,然后返回一个包含所有 Note 对象的列表。

4.3.4 cursor介绍

        上一节中有关于cursor的地方,现在介绍一下:

        Cursor 是 Android 中用于与数据库查询结果交互的类。它提供了一种方式来遍历查询结果集中的各个行,并允许从每一行中提取数据。

        在上面的代码中,Cursor 是通过调用 db.query() 方法返回的查询结果集。它代表了数据库查询的结果集,包含了满足查询条件的所有行。可以使用 Cursor 对象来遍历查询结果集,并提取每一行中的数据。

         Cursor 对象提供了一系列方法来移动光标以及从当前行中获取数据,如 moveToFirst()、moveToNext()、getString()、getInt() 等。通过这些方法,可以获取查询结果集中的各个字段的值,并进行相应的处理。

        cursor 变量代表了查询结果集的一个游标,通过调用 cursor.moveToFirst() 方法,将游标移动到结果集的第一行,然后可以使用 cursor.getString()、cursor.getInt() 等方法来从当前行中提取数据。

        在上面的代码中执行 cursor.moveToFirst() 的目的是将光标移动到查询结果集的第一行。这是因为在执行数据库查询后,光标的初始位置通常是在查询结果集之前,通过调用 moveToFirst() 方法可以将光标移动到结果集的第一行,以便开始处理查询结果。        

4.3.5  改方法

        这段代码是用于更新数据库中的记录的方法。

        创建一个 ContentValues 对象,用于存储要更新的数据。 使用 put() 方法将 note 对象的内容、时间和标签放入 ContentValues 对象中,使用的键分别对应数据库表中的列名。

         调用 db.update() 方法更新数据库表中的记录,传入要更新的表名、更新的数据集合 values、更新条件和更新条件的参数。 更新条件通过 NoteDatabase.ID + "=?" 指定,这里使用的是 NoteDatabase.ID 字段作为更新条件,通过 String.valueOf(note.getId()) 获取要更新的记录的 ID,并将其作为参数传递给 db.update() 方法。

         db.update() 方法返回一个整数值,表示受影响的行数,即成功更新的记录数。

        总的来说,这段代码实现了更新数据库表中特定 ID 的记录,将其内容、时间和标签更新为 note 对象中对应的值,并返回成功更新的记录数。

4.3.6 删方法

        这段代码是用于从数据库中删除特定记录的方法。

        使用 db.delete() 方法从数据库表中删除记录,传入要删除的表名、删除条件和删除条件的参数。 删除条件通过 NoteDatabase.ID + "=" + note.getId() 指定,这里使用的是 NoteDatabase.ID 字段作为删除条件,并将要删除的记录的 ID 作为参数传递给 db.delete() 方法。 db.delete() 方法不返回任何值,它会直接删除满足条件的记录。

         总的来说,这段代码实现了从数据库表中删除特定 ID 的记录。通过指定删除条件,可以删除满足特定条件的记录。

4.4 总结

        经过前面的3步操作之后,我们就可以执行数据库操作了。

        上图可以看到我们首先创建了CRUD对象,从而创建了这个note数据库,接着我们打开数据库连接,向数据库中添加一条note数据,最后关闭连接。

        详细过程:

        首先,创建了一个 CRUD 对象,这个对象内部持有一个 NoteDatabase 对象,其中 NoteDatabase 继承自 SQLiteOpenHelper,负责创建和管理数据库。 在创建 CRUD 对象时,会创建一个 NoteDatabase 对象,从而创建了数据库。

         接着,调用 open() 方法打开数据库连接。在 open() 方法中,会获取可写的数据库连接,并将其赋值给 SQLiteDatabase db 对象。

        然后,调用 addNote() 方法向数据库中添加一条 Note 数据。在 addNote() 方法中,会将数据添加到数据库表中,并返回插入数据的 ID。

         最后,调用 close() 方法关闭数据库连接。在 close() 方法中,会关闭数据库帮助类 NoteDatabase,释放相关资源。

        完整的代码如下所示:

package com.xht.note;import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;import java.util.ArrayList;
import java.util.List;public class CRUD {SQLiteDatabase db;SQLiteOpenHelper dbHandler;private static final String[] columns = {NoteDatabase.ID,NoteDatabase.CONTENT,NoteDatabase.TIME,NoteDatabase.MODE};public CRUD(Context context) {dbHandler = new NoteDatabase(context);}public void open(){db = dbHandler.getWritableDatabase();}public void close(){dbHandler.close();}public Note addNote(Note note){ContentValues contentValues = new ContentValues();contentValues.put(NoteDatabase.CONTENT, note.getContent());contentValues.put(NoteDatabase.TIME, note.getTime());contentValues.put(NoteDatabase.MODE, note.getTag());long insetId = db.insert(NoteDatabase.TABLE_NAME, null, contentValues);note.setId(insetId);return note;}public Note getNote(long id){Cursor cursor = db.query(NoteDatabase.TABLE_NAME,columns, NoteDatabase.ID + "=?",new String[]{String.valueOf(id)}, null, null, null, null );if(cursor != null){cursor.moveToFirst();}Note e = new Note(cursor.getString(1), cursor.getString(2), cursor.getInt(3));return e;}@SuppressLint("Range")public List<Note> getAllNotes(){Cursor cursor = db.query(NoteDatabase.TABLE_NAME, columns, null, null,null, null, null);List<Note> notes = new ArrayList<>();if(cursor.getCount() > 0){
//            Cursor 对象最开始指向查询结果集的第一行之前的位置,也就是在第一行之前的"假想"位置while(cursor.moveToNext()){Note note = new Note();note.setId(cursor.getLong(cursor.getColumnIndex(NoteDatabase.ID)));note.setContent(cursor.getString(cursor.getColumnIndex(NoteDatabase.CONTENT)));note.setTime(cursor.getString(cursor.getColumnIndex(NoteDatabase.TIME)));note.setTag(cursor.getInt(cursor.getColumnIndex(NoteDatabase.MODE)));notes.add(note);}}return notes;}public int updateNote(Note note){ContentValues values = new ContentValues();values.put(NoteDatabase.CONTENT, note.getContent());values.put(NoteDatabase.TIME, note.getTime());values.put(NoteDatabase.MODE, note.getTag());return db.update(NoteDatabase.TABLE_NAME, values,NoteDatabase.ID + "=?", new String[]{String.valueOf(note.getId())});}public void removeNote(Note note){db.delete(NoteDatabase.TABLE_NAME, NoteDatabase.ID + "=" + note.getId(), null);}
}

5. ListView及adapter

         这一章的note类是沿用上一章的note笔记类,CRUD操作等都沿用了上一章。

        在Android开发中,ListView是用于显示可滚动列表项的组件,而适配器(Adapter)则用于将数据绑定到ListView上,并负责将数据转换为可视的列表项。

         适配器在ListView中扮演着至关重要的角色,它负责以下几个方面的工作:

  • 数据绑定: 适配器负责将数据集合绑定到ListView上,以便在列表中显示。它从数据集合中获取数据,并将其填充到ListView的列表项中。
  • 视图创建: 适配器负责根据数据集合的内容创建ListView中的每个列表项的视图。通常,它会根据布局文件创建视图,并将数据填充到相应的视图控件中。
  • 列表项重用: 为了提高性能,ListView会重用已经滚出屏幕的列表项的视图。适配器负责处理列表项的重用,确保适当的视图被填充到相应的数据上。
  • 数据更新: 当数据集合发生变化时,适配器负责通知ListView刷新列表视图,以反映最新的数据。这通常通过调用适配器的notifyDataSetChanged()方法来实现。
  • 事件处理: 适配器还可以处理ListView中列表项的事件,例如点击事件、长按事件等。它可以通过设置监听器来处理这些事件,并在发生事件时执行相应的操作。
  • 总之,适配器在Android中扮演了连接数据和UI的重要角色,它使得将数据显示为可滚动的列表变得更加简单和高效。通过适配器,开发者可以轻松地将各种数据集合以列表形式展示在ListView中,并对列表项进行定制和处理。
5.1 note类的适配器

        NoteAdapter 类是一个继承自 BaseAdapter 并实现了 Filterable 接口的适配器类。这个类的目的是将 Note 对象列表展示在 ListView 或者 GridView 中,并且支持根据过滤条件进行过滤(过滤部分先不考虑)。

        Context mContext: 用于存储上下文,通常是关联的 Activity 的上下文。

         List<Note> backList: 存储Note 列表的备份。

         List<Note> noteList: 存储当前的 Note 列表。

        构造函数: 构造函数接收一个 Context 对象和一个 noteList 列表作为参数,分别用于初始化 mContext 和 noteList。 backList 在构造函数中被初始化为传入的 noteList,作为原始数据的备份。

         这四个方法是实现 BaseAdapter 的必需方法:

        getCount(): 这个方法返回数据集中的项数,也就是要在 ListView 或 GridView 中显示的项的数量。 在这里,它返回了 noteList 的大小,即 Note 对象列表的长度。

        getItem(int position): 这个方法返回数据集中指定位置的项。 在这里,它返回了 noteList 中指定位置的 Note 对象。

        getItemId(int position): 这个方法返回指定位置项的行 ID。 在这里,它返回的是指定位置的索引,因为 Note 对象没有行 ID,所以使用其位置作为 ID。

        这些方法是必需的,用于告知适配器有关数据集的信息,以便适配器能够正确地在 ListView 或 GridView 中显示数据。

        在 getView() 方法中,主要完成了以下几个任务:

        创建或获取 View 对象: 通过 View.inflate() 方法从布局文件 R.layout.note_layout 中创建一个新的 View 对象。这个布局文件通常定义了每个 ListView 或 GridView 中项的外观和布局。

        note_layout里定义了两个textView,第一行显示笔记的内容,第二行显示写笔记时的时间。

        查找子视图并设置数据: 通过 findViewById() 方法在新创建的 View 中查找并获取 TextView 对象,用于显示笔记的内容和时间。

        将 noteList 中指定位置的 Note 对象的内容和时间分别设置到对应的 TextView 中。

        设置标签: 使用 setTag() 方法为该项的根视图设置一个标签,标签的值是 Note 对象的 ID。        

        返回 View 对象: 返回刚刚创建的 View 对象,该对象包含了显示笔记内容和时间的 TextView的根视图。

         总的来说,getView() 方法负责根据数据集中的数据创建或获取视图,并将数据绑定到视图上,最后返回这个视图。上图中,该方法返回的视图显示了笔记的内容和时间,并且标记了笔记的 ID。

        在这个 getView() 方法中,v 是每个列表项的视图,而不是集合中所有数据的视图。noteList 是数据集合,其中包含了要在列表中显示的所有数据。在 getView() 方法中,适配器根据每个数据项创建相应的视图,并将其返回用于显示在列表中。

        具体来说,getView() 方法在每次列表需要显示一个新的列表项时被调用。在这个方法中,我们通过 View.inflate() 方法从布局文件 note_layout 中创建了一个新的视图 v。然后,我们在这个视图中找到了 TextView 控件 tv_content 和 tv_time,并将数据集合 noteList 中当前位置 position 对应的数据填充到这些控件中。

        因此,v 是一个列表项的视图,而不是集合中所有数据的视图。在 getView() 方法中,我们为每个数据项创建一个视图,并将其返回用于显示在列表中。当列表需要显示多个数据项时,getView() 方法会被多次调用,每次都会返回一个新的列表项视图。

        完整代码如下所示:

package com.xht.note;import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;import java.util.List;public class NoteAdapter extends BaseAdapter implements Filterable {private Context mContext;private List<Note> backList;private List<Note> noteList;private MyFilter myFilter;public NoteAdapter(Context mContext, List<Note> noteList) {this.mContext = mContext;this.noteList = noteList;backList = noteList;}@Overridepublic int getCount() {return noteList.size();}@Overridepublic Object getItem(int position) {return noteList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View converView, ViewGroup parent) {//!!!!!mContext.setTheme(R.style.DayTheme);View v = View.inflate(mContext, R.layout.note_layout, null);TextView tv_content = (TextView) v.findViewById(R.id.tv_content);TextView tv_time = (TextView) v.findViewById(R.id.tv_time);String allText = noteList.get(position).getContent();tv_content.setText(allText);tv_time.setText(noteList.get(position).getTime());
//        ?????v.setTag(noteList.get(position).getId());return v;}class MyFilter extends Filter {@Overrideprotected FilterResults performFiltering(CharSequence constraint) {return null;}@Overrideprotected void publishResults(CharSequence constraint, FilterResults results) {}}@Overridepublic Filter getFilter() {if(myFilter == null){myFilter = new MyFilter();}return myFilter;}
}
5.2 ListView显示数据

        创建一个新的笔记的适配器: NoteAdapter 对象,并调用一个名为 refreshListView() 的方法,用于刷新显示笔记的列表视图。

上上图中的lv指这个图中的ListView

        这段代码是用于刷新显示笔记的列表视图的方法 refreshListView() 的实现。

        CRUD op = new CRUD(context); 首先,创建了一个 CRUD 对象 op,用于执行数据库操作。 CRUD 类似于一个数据访问对象(DAO),用于执行对数据库的增删改查操作。

         op.open(); 打开了数据库连接,以便执行数据库操作。

        if(noteList.size() > 0){ noteList.clear(); } 检查 noteList 是否为空,如果不为空,则清空 noteList 中的所有数据。 这一步是为了确保在刷新列表之前先清空旧数据,以便加载最新的数据。         noteList.addAll(op.getAllNotes()); 通过调用 op.getAllNotes() 方法,从数据库中获取所有的笔记数据,并将其添加到 noteList 中。 getAllNotes() 方法返回一个 List<Note>,其中包含了所有的笔记数据。

        op.close(); 关闭了数据库连接,释放资源。

         adapter.notifyDataSetChanged(); 调用 adapter.notifyDataSetChanged() 方法,通知适配器数据已经改变,需要刷新列表视图。 这一步是为了告诉适配器,数据已经更新,需要重新加载显示在列表中。

        综上所述,refreshListView() 方法的作用是从数据库中获取最新的笔记数据,更新 noteList,并通知适配器刷新列表视图,以显示最新的数据。

        adapter.notifyDataSetChanged() 是一个用于通知适配器数据已经发生变化的方法。当调用这个方法时,适配器会通知与其相关联的ListView(或GridView等)重新加载数据并刷新显示。

        当调用 adapter.notifyDataSetChanged() 方法时,Android 系统会自动触发列表视图的刷新过程。在这个过程中,系统会重新调用适配器的 getView() 方法来获取每个列表项的视图。在 getView() 方法中,适配器会根据最新的数据集合重新创建列表项的视图,并将其显示在列表中。

         这个方法的作用是告诉适配器数据已经发生了改变,需要重新加载并刷新显示在列表视图中。适配器会根据新的数据集合重新创建列表项的视图,并将其显示在列表中。

        

        最终实现图:

可以看到把数据库的note数据都读取出来后,显示在ListView里。

package com.xht.note;import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;import com.google.android.material.floatingactionbutton.FloatingActionButton;import java.util.ArrayList;
import java.util.List;public class MainActivity extends BaseActivity {final String TAG = "tag";FloatingActionButton btn;TextView tv;private ListView lv;private NoteDatabase dbHelper;private NoteAdapter adapter;private List<Note> noteList = new ArrayList<>();private Context context = this;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn = (FloatingActionButton) findViewById(R.id.fab);
//        tv = findViewById(R.id.tv);lv = findViewById(R.id.lv);
//        adapter = new NoteAdapter(getApplicationContext(), noteList);adapter = new NoteAdapter(context, noteList);refreshListView();lv.setAdapter(adapter);ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),new ActivityResultCallback<ActivityResult>() {@Overridepublic void onActivityResult(ActivityResult result) {//判断是否传入正确的resultif(result.getResultCode() == RESULT_OK){Intent intent = result.getData();   //获取上一个活动返回的Intent//判断上一个活动的Intent是否存在,存在则在日志中输入if(intent != null){String content = intent.getStringExtra("content");String time = intent.getStringExtra("time");Note note = new Note(content, time, 1);//数据库操作CRUD op = new CRUD(context);op.open();op.addNote(note);op.close();refreshListView();
//                                Log.d(TAG, edit);
//                                tv.setText(edit);}}}});btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {
//                Log.d(TAG, "Onclick: click");Intent intent = new Intent(MainActivity.this, EditActivity.class);//向下传递IntentresultLauncher.launch(intent);}});}public void refreshListView(){CRUD op = new CRUD(context);op.open();// set adpterif(noteList.size() > 0){noteList.clear();}noteList.addAll(op.getAllNotes());op.close();adapter.notifyDataSetChanged();}
}

5.3 点击ListView的各项进行编辑

效果演示:

笔记页面:

点击111222笔记,进入编辑页面

 实现方法:

        在 MainActivity 类中,首先需要实现 AdapterView.OnItemClickListener 接口,并将其设置为 ListView 的点击监听器,然后才能覆写 onItemClick 方法。在 onItemClick 方法中,可以处理 ListView 的点击事件,并根据点击的位置获取相应的数据,然后创建 Intent 并将数据传递到另一个活动中。最后,可以使用 resultLauncher.launch(intent) 启动目标活动,并在需要时设置返回结果。

分步解释:

        首先:让当前类implements AdapterView.OnItemClickListener:通过实现 AdapterView.OnItemClickListener 接口,指示 MainActivity 类能够处理 ListView 的点击事件。

        其次lv = findViewById(R.id.lv);:通过 findViewById 方法找到布局中的 ListView 控件,并将其赋值给 lv 变量,以便后续操作。

        lv.setOnItemClickListener(this);:将当前活动(MainActivity)设置为 ListView 的点击事件监听器。这样一来,当用户点击 ListView 中的任何项时,就会触发 onItemClick 方法,然后由当前活动(MainActivity)来处理该点击事件。通过设置点击事件监听器,可以实现对 ListView 点击事件的响应和处理。

        最后:@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id):覆写 AdapterView.OnItemClickListener 接口中的 onItemClick 方法,以实现自定义的点击事件处理逻辑。

        onItemClick(AdapterView<?> parent, View view, int position, long id) 方法是 AdapterView.OnItemClickListener 接口中的一个回调方法,用于处理 ListView(或其他 AdapterView)中项的点击事件。 当你将一个 OnItemClickListener 设置给 ListView 时,每次用户点击 ListView 中的项时,Android 系统就会调用这个方法。

        方法的参数包括: parent:指向 ListView 对象本身,即被点击的 ListView。 view:指向被点击的项所对应的 View 对象。 position:被点击项在 ListView 中的位置。 id:被点击项的行 ID。

        使用该方法后,点击 ListView 中的项会有效果,是因为系统会调用这个方法来处理点击事件,从而触发在方法中定义的操作。

代码:

package com.xht.note;import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;import com.google.android.material.floatingactionbutton.FloatingActionButton;import java.util.ArrayList;
import java.util.List;public class MainActivity extends BaseActivityimplements AdapterView.OnItemClickListener {final String TAG = "tag";FloatingActionButton btn;TextView tv;private ListView lv;private NoteDatabase dbHelper;private NoteAdapter adapter;private List<Note> noteList = new ArrayList<>();private Context context = this;private Toolbar myToolBar;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn = (FloatingActionButton) findViewById(R.id.fab);
//        tv = findViewById(R.id.tv);lv = findViewById(R.id.lv);myToolBar = findViewById(R.id.myToolBar);
//        adapter = new NoteAdapter(getApplicationContext(), noteList);adapter = new NoteAdapter(context, noteList);refreshListView();lv.setAdapter(adapter);//设置toolbar取代actionBarsetSupportActionBar(myToolBar);getSupportActionBar().setHomeButtonEnabled(true);getSupportActionBar().setDisplayHomeAsUpEnabled(true);lv.setOnItemClickListener(this);btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {
//                Log.d(TAG, "Onclick: click");Intent intent = new Intent(MainActivity.this, EditActivity.class);intent.putExtra("mode", 4);//向下传递IntentresultLauncher.launch(intent);}});}public void refreshListView(){CRUD op = new CRUD(context);op.open();// set adpterif(noteList.size() > 0){noteList.clear();}noteList.addAll(op.getAllNotes());op.close();adapter.notifyDataSetChanged();}ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),new ActivityResultCallback<ActivityResult>() {@Overridepublic void onActivityResult(ActivityResult result) {//判断是否传入正确的resultif(result.getResultCode() == RESULT_OK){int returnMode;long note_Id;Intent data = result.getData();returnMode = data.getExtras().getInt("mode", -1);
//                        Log.d("xht", returnMode +"");note_Id = data.getExtras().getLong("id", 0);if(returnMode == 1){// update current noteString  content = data.getExtras().getString("content");String time = data.getExtras().getString("time");int tag = data.getExtras().getInt("tag", 1);Note newNote = new Note(content, time, tag);newNote.setId(note_Id);CRUD op = new CRUD(context);op.open();op.updateNote(newNote);op.close();}else if(returnMode == 0){// create new noteString  content = data.getExtras().getString("content");String time = data.getExtras().getString("time");int tag = data.getExtras().getInt("tag", 1);Note newNote = new Note(content, time, tag);
//                            Log.d("content", content);CRUD op = new CRUD(context);op.open();op.addNote(newNote);op.close();}else{}refreshListView();
//                        Intent intent = result.getData();   //获取上一个活动返回的Intent
//                        //判断上一个活动的Intent是否存在,存在则在日志中输入
//                        if(intent != null){
//                            String content = intent.getStringExtra("content");
//                            String time = intent.getStringExtra("time");
//                            Note note = new Note(content, time, 1);
//                            //数据库操作
//                            CRUD op = new CRUD(context);
//                            op.open();
//                            op.addNote(note);
//                            op.close();
//                            refreshListView();Log.d(TAG, edit);tv.setText(edit);
//
//                        }}}});@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {if (parent.getId() == R.id.lv){Note curNote = (Note) parent.getItemAtPosition(position);Intent intent = new Intent(MainActivity.this, EditActivity.class);intent.putExtra("content", curNote.getContent());intent.putExtra("id", curNote.getId());intent.putExtra("time", curNote.getTime());intent.putExtra("mode", 3);intent.putExtra("tag", curNote.getTag());setResult(1,intent);resultLauncher.launch(intent);Log.d(TAG, "content:" + curNote.getContent());}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/475838.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最长子串和回文子串相关的算法题解

这里写目录标题 一、3. 无重复字符的最长子串二、5. 最长回文子串三、647. 回文子串四、516. 最长回文子序列 一、3. 无重复字符的最长子串 中等 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释:…

手把手教你Linux系统下的Java环境配置,简单到不行!

推荐阅读 给软件行业带来了春天——揭秘Spring究竟是何方神圣&#xff08;一&#xff09; 给软件行业带来了春天——揭秘Spring究竟是何方神圣&#xff08;二&#xff09; 文章目录 推荐阅读下载JDK安装包方式一方式二 添加环境变量验证安装情况 下载JDK安装包 方式一 1.进入…

第三百五十二回

文章目录 1. 概念介绍2. 获取方法3. 示例代码4. 对比与总结4.1 横向对比4.2 内容总结 我们在上一章回中介绍了"如何获取当前系统语言"相关的内容&#xff0c;本章回中将介绍如何获取当前时区.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们使用的…

第三百五十三回

文章目录 1. 概念介绍2. 使用方法2.1 获取所有时区2.2 转换时区时间 3. 示例代码4. 内容总结 我们在上一章回中介绍了"分享一些好的Flutter站点"相关的内容&#xff0c;本章回中将介绍timezone包.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在…

【PX4-AutoPilot教程-源码】移植PX4固件到自制NuttX操作系统飞控板的方法

移植PX4固件到自制NuttX操作系统飞控板的方法 找到使用相同&#xff08;或型号相似&#xff09;CPU类型的现有目标并进行复制飞控板的配置文件夹结构firmware.prototype文件default.px4board文件bootloader.px4board文件nuttx-config/bootloader/defconfig文件nuttx-config/nsh…

阿莱(ARRI)MOV变0字节恢复案例

阿莱(ARRI)是专业级的影视产品软硬件供应商&#xff0c;很多大片都是使用ARRI的设备拍摄出来的。之前我们处理过阿莱的MXF和MOV等文件&#xff0c;今天要说的案例是ARRI的MOV&#xff0c;还是之前熟悉的EXFAT文件系统然后长度突然变0字节的问题。 故障存储:16T/MS Exfat文件系…

如何在Linux系统中配置并优化硬盘的RAID

在Linux系统中配置和优化硬盘的RAID技术可以帮助提高数据存储性能和安全性。RAID&#xff08;Redundant Array of Independent Disks&#xff09;技术通过将多个硬盘组合起来&#xff0c;以增加性能、容量或冗余度&#xff0c;提高数据的可靠性和可用性。本文将介绍如何在Linux…

Days 34 ElfBoard 音频接口

音频接口介绍 音频模块采用了 NAU88C22 芯片&#xff0c;芯片数据信号使用 I2S 接口进行通讯&#xff0c;主要信号功能&#xff1a; SAI_MCLK&#xff1a;音频信号主时钟&#xff1b; SAI_BCLK&#xff1a;音频信号位时钟&#xff1b; SAI_SYNC&#xff1a;左右声道控制信号&am…

综合练习

目录 查询每个员工的编号、姓名、职位、基本工资、部门名称、部门位置 确定要使用的数据表 确定已知的关联字段 查询每个员工的编号、姓名、职位、基本工资、工资等级 确定要使用的数据表 确定已知的关联字段 查询每个员工的编号、姓名、职位、基本工资、部门名称、工资…

用Boule绘制地球重力场

文章目录 参考椭球标准重力重力地图 参考椭球 boule中定义了多种参考椭球&#xff0c;可用于表示地球、火星等星体的重力分布。可通过pip安装 pip install boule安装完成后可直接调用 import boule as blboule中已经定义的椭球如下 椭球星体GRS80地球WGS84地球MARS火星MERC…

linux内核模块module_put()函数详解--03

对应module_put()函数详细用法分享。 第一&#xff1a;函数简介 //函数原型 void module_put(struct module * module) //函数功能 该函数功能是将一个特定模块module的引用计数减一 这样当一个模块的引用计数不为0而不能被内核卸载的 时候&#xff0c;可以调用该函数一次或多…

【嵌入式学习】IO网络接口day02.18

1.使用fgets统计给定文件的行数 #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, const char *argv[]) {FILE *fpNULL;if((fpfopen("./test1.txt","r"))NULL){perror("错误信息");return -1…