弱龄寄事外,委怀在琴书。这篇文章主要讲述安卓记事本小程序开发相关的知识,希望能为你提供帮助。
这几天用自己目前掌握的安卓开发知识制作了一个记事本小程序,在这里分享一下开发流程,希望可以帮到和我一样的初学者。
开发工具为android studio,后台语言为java,使用的数据库为安卓的SQLite数据库,功能及效果图如下:
主界面,长按可删除:
文章图片
文章图片
【安卓记事本小程序开发】
点击加号添加:
文章图片
主页面点击查看,此页面含修改和删除功能:
文章图片
文章图片
主要使用的技术:数据存储使用的数据库存储,我之前的博客有讲过安卓SQLite的基础操作;数据的显示用的是ListView部件,数据传输用的是intent技术,页面间的跳转也是借助intent; 主页点击某一行,就通过intent传递其id到查看页,并根据id从数据库中读取数据进行显示,删除也是根据id进行数据库操作。
整个项目文件已经同步到github需要的请自取https://github.com/liuleliu/textbook
下面是主要代码:
数据库辅助类:
package com.example.myapplication; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DataBaseHelp extends SQLiteOpenHelper{ private static final String DATABASENAME ="tip1"; //数据库名称 private static final int DATABASEVERSION =1; //数据库版本 private static final String TABLENAME="tip1"; //表名 public DataBaseHelp(Context context)//定义构造 { super(context,DATABASENAME,null,DATABASEVERSION); //调用父类构造 } public void onCreate(SQLiteDatabase db) { String sql="CREATE TABLE "+TABLENAME+"("+ "idINTEGER PRIMARY KEY AUTOINCREMENT,"+//设置自动增长列 "nameVARCHAR(50) NOT NULL,"+ "textVARCHAR(50) NOT NULL)"; db.execSQL(sql); //执行sql语句 } public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion) { String sql="DROP TABLE IF EXISTS "+TABLENAME; db.execSQL(sql); this.onCreate(db); //创建表} }
操作类
package com.example.myapplication; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class OperateTable { private static final String TABLENAME ="tip1"; private SQLiteDatabase db=null; public OperateTable(SQLiteDatabase db) { this.db=db; } public void insert(String name,String text) { String sql="INSERT INTO "+TABLENAME+" (name,text) VALUES (\'"+name+"\',\'"+text+"\')"; this.db.execSQL(sql); } public void delete(String id) { String sql="DELETE FROM "+TABLENAME+" WHERE id=\'"+id+"\'"; this.db.execSQL(sql); } public void updata(String id,String name,String text) { String sql="UPDATE "+TABLENAME+" SET name =\'"+name+"\',text=\'"+text+"\' WHERE id=\'"+id+"\'"; this.db.execSQL(sql); } public List< Map< String,Object> > getdata() {List< Map< String,Object> > list=new ArrayList< Map< String,Object> > (); Map< String,Object> map=new HashMap< String,Object> (); String sql="SELECT id,name,text FROM "+TABLENAME; Cursor result =this.db.rawQuery(sql,null); for(result.moveToFirst(); !result.isAfterLast(); result.moveToNext()) { map=new HashMap< String,Object> (); map.put("id",result.getInt(0)); map.put("tt",result.getString(1)); list.add(map); } returnlist; } public tip t(String id) { tip t=new tip(); String sql="SELECT name,text FROM "+TABLENAME+" WHERE id =\'"+id+"\'"; Cursor result =this.db.rawQuery(sql,null); result.moveToFirst(); t.setName(result.getString(0)); t.setText(result.getString(1)); return t; } }
主页的数据显示以及互动涉及到了ListView的使用
数据的更新要重载onResume()函数来实现
布局:
< ?xml version="1.0" encoding="utf-8"?> < androidx.constraintlayout.widget.ConstraintLayout 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/linearLayout2" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> < com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/add" android:layout_width="59dp" android:layout_height="57dp" android:layout_marginEnd="28dp" android:clickable="true" app:backgroundTint="#2894FF" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.807" app:srcCompat="@android:drawable/ic_input_add" /> < ListView android:id="@+id/vi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:layout_marginBottom="389dp" app:layout_constraintBottom_toTopOf="@+id/add" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.034"> < /ListView> < /androidx.constraintlayout.widget.ConstraintLayout>
下面这个是每一行的布局
< TextView android:id="@+id/id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="39dp" android:layout_marginBottom="24dp" android:text="TextView" android:textColor="#00000000" app:layout_constraintBottom_toBottomOf="@+id/pic" app:layout_constraintStart_toStartOf="parent" /> < ImageView android:id="@+id/pic" android:layout_width="142dp" android:layout_height="101dp" android:src="https://www.songbingjia.com/android/@mipmap/ic_launcher_round" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> < /androidx.constraintlayout.widget.ConstraintLayout>
然后是在主类中的操作,为ListView赋值,设置交互事件(单机,长按)
package com.example.myapplication; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import android.content.DialogInterface; import android.content.Intent; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Toast; import com.google.android.material.floatingactionbutton.FloatingActionButton; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class MainActivity extends AppCompatActivity { private OperateTable mytable =null; private SQLiteOpenHelper helper=null; private FloatingActionButton add=null; private String info=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); helper=new DataBaseHelp(this); helper.getWritableDatabase(); MainActivity.this.mytable=new OperateTable(MainActivity.this.helper.getWritableDatabase()); SimpleAdapter adapter = new SimpleAdapter(this,this.mytable.getdata(), R.layout.activity_main , new String[]{"id","tt"}, new int[]{R.id.id,R.id.tt}); ListView listView=(ListView)findViewById(R.id.vi); add=(FloatingActionButton)findViewById(R.id.add); listView.setAdapter(adapter); listView.setOnItemClickListener(new OnItemClick()); //注册单击监听 listView.setOnItemLongClickListener(new OnItemLongClick()); //注册长按监听 add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent it=new Intent(MainActivity.this,add.class); MainActivity.this.startActivity(it); } }); }private class OnItemClick implements AdapterView.OnItemClickListener { public void onItemClick(AdapterView< ?> arg0, View arg1, int arg2, long arg3){ ListView list = (ListView) findViewById(R.id.vi); HashMap< String,Object> map=(HashMap< String,Object> )list.getItemAtPosition(arg2); info=map.get("id").toString(); Intent it=new Intent(MainActivity.this,receive.class); it.putExtra("info",info); //传输数据到receive MainActivity.this.startActivity(it); }} private class OnItemLongClick implements AdapterView.OnItemLongClickListener { public boolean onItemLongClick(AdapterView< ?> arg0, View arg1, int arg2, long arg3){ListView list = (ListView) findViewById(R.id.vi); HashMap< String,Object> map=(HashMap< String,Object> )list.getItemAtPosition(arg2); String name; info=map.get("id").toString(); name=map.get("tt").toString(); AlertDialog myAlertDialog = new AlertDialog.Builder(MainActivity.this) .setTitle("确认" ) .setMessage("确定删除“"+name+"”吗?" ) .setPositiveButton("是" , new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { mytable.delete(info); Toast.makeText(getApplicationContext(),"删除成功",Toast.LENGTH_SHORT).show(); onResume(); } }) .setNegativeButton("否" , null) .show(); return true; }}//每次回到主页就会执行,用于更新数据 public void onResume() { super.onResume(); // Always call the superclass method firstSimpleAdapter adapter = new SimpleAdapter(this,MainActivity.this.mytable.getdata(), R.layout.activity_main , new String[]{"id","tt"}, new int[]{R.id.id,R.id.tt}); ListView listView=(ListView)findViewById(R.id.vi); add=(FloatingActionButton)findViewById(R.id.add); listView.setAdapter(adapter); listView.setOnItemClickListener(new OnItemClick()); add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent it=new Intent(MainActivity.this,add.class); MainActivity.this.startActivity(it); } }); }}
添加比较简单,就是获取数据并调用数据库操作保存数据
布局
< ?xml version="1.0" encoding="utf-8"?> < androidx.constraintlayout.widget.ConstraintLayout 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/linearLayout3" android:layout_width="match_parent" android:layout_height="match_parent"> < EditText android:id="@+id/aname" android:layout_width="283dp" android:layout_height="0dp" android:layout_marginStart="60dp" android:layout_marginTop="26dp" android:layout_marginBottom="461dp" android:hint="标题" android:maxLines="1" android:maxLength="25" app:layout_constraintBottom_toTopOf="@+id/save" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> < /EditText> < EditText android:id="@+id/atext" android:layout_width="335dp" android:layout_height="426dp" android:layout_marginStart="43dp" android:layout_marginBottom="84dp" android:hint="内容" android:minLines="5" android:gravity="top" android:background="@null" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/aname"> < /EditText> < Button android:id="@+id/save" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="17dp" android:text="保存" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="@+id/atext" app:layout_constraintTop_toBottomOf="@+id/aname" /> < /androidx.constraintlayout.widget.ConstraintLayout>
活动类
package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class add extends AppCompatActivity { privateOperateTable mytable =null; privateSQLiteOpenHelper helper=null; private EditText name=null; private EditText text=null; privateButton save=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.add); this.name=(EditText)super.findViewById(R.id.aname); this.text=(EditText)super.findViewById(R.id.atext); Button save=( Button) super.findViewById(R.id.save); helper=new DataBaseHelp(this); helper.getWritableDatabase(); mytable=new OperateTable(helper.getWritableDatabase()); save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(name.getText().toString().equals("")){Toast.makeText(getApplicationContext(),"请输入标题",Toast.LENGTH_SHORT).show(); } else{ mytable.insert(name.getText().toString(),text.getText().toString()); //保存数据 Toast.makeText(getApplicationContext(),"保存成功",Toast.LENGTH_SHORT).show(); add.this.finish(); //结束当前Activity,返回主页面}} }); }}
查看页,接收来自主页通过intent传来的id,获取相应数据并显示
布局:
< ?xml version="1.0" encoding="utf-8"?> < androidx.constraintlayout.widget.ConstraintLayout 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/linearLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> < EditText android:id="@+id/name" android:layout_width="303dp" android:layout_height="46dp" android:layout_marginStart="60dp" android:layout_marginTop="36dp" android:layout_marginBottom="14dp" android:hint="标题" android:text="TextView" android:maxLength="25" app:layout_constraintBottom_toTopOf="@+id/divider" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> < EditText android:id="@+id/text" android:layout_width="308dp" android:layout_height="400dp" android:layout_marginStart="52dp" android:layout_marginEnd="52dp" android:layout_marginBottom="63dp" android:background="@null" android:gravity="top" android:hint="内容" android:minLines="5" android:text="TextView" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/name" app:layout_constraintVertical_bias="1.0" /> < View android:id="@+id/divider" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="1dp" android:layout_marginTop="83dp" android:layout_marginEnd="1dp" android:layout_marginBottom="433dp"android:background="?android:attr/listDivider" app:layout_constraintBottom_toTopOf="@+id/delete" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> < Button android:id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="29dp" android:layout_marginBottom="6dp" android:text="删除" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/divider" /> < Button android:id="@+id/edit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="29dp" android:layout_marginBottom="7dp" android:text="保存更改" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" /> < /androidx.constraintlayout.widget.ConstraintLayout>
活动类
package com.example.myapplication; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import android.content.DialogInterface; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.content.Intent; import android.widget.Toast; public class receive extends AppCompatActivity {private EditText name=null; private EditText text=null; private Button delete=null; private Button edit=null; private OperateTable mytable =null; private SQLiteOpenHelper helper=null; private String info=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.receive); this.name=(EditText)super.findViewById(R.id.name); this.text=(EditText)super.findViewById(R.id.text); this.delete=(Button)super.findViewById(R.id.delete); this.edit=(Button)super.findViewById(R.id.edit); Intent it=super.getIntent(); info=it.getStringExtra("info"); //获取主页传递的idhelper=new DataBaseHelp(this); helper.getWritableDatabase(); mytable=new OperateTable(helper.getWritableDatabase()); tip t=mytable.t(info); name.setText(t.getName()); text.setText(t.getText()); delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { AlertDialog myAlertDialog = new AlertDialog.Builder(receive.this) .setTitle("确认" ) .setMessage("确定删除“"+name.getText()+"”吗?" ) .setPositiveButton("是" , new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { mytable.delete(info); Toast.makeText(getApplicationContext(),"删除成功",Toast.LENGTH_SHORT).show(); receive.this.finish(); } }) .setNegativeButton("否" , null) .show(); } }); edit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mytable.updata(info,name.getText().toString(),text.getText().toString()); Toast.makeText(getApplicationContext(),"修改成功",Toast.LENGTH_SHORT).show(); receive.this.finish(); } }); }}
推荐阅读
- android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a vi
- Android Studiio安装
- 关于app.use('/static', express.static(path.join(__dirname, 'public')))的理解
- Android基础——基本UI控件()
- Windows 8中通过TCP/IP禁用NetBIOS
- 已解决(Can’t locate IO/Socket/SSL.pm in @INC)
- 已解决(configure: error: MySQL library not found)
- 通过这六个网站从Web浏览器运行Linux
- 什么是DQL()