景泽元的编程 2020-01-23
这几天用自己目前掌握的安卓开发知识制作了一个记事本小程序,在这里分享一下开发流程,希望可以帮到和我一样的初学者。
开发工具为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+"("+ "id INTEGER PRIMARY KEY AUTOINCREMENT,"+ //设置自动增长列 "name VARCHAR(50) NOT NULL,"+ "text VARCHAR(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); } return list;} 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="@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 first SimpleAdapter 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 { private OperateTable mytable =null; private SQLiteOpenHelper helper=null; private EditText name=null; private EditText text=null; private Button 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");//获取主页传递的id helper=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(); } }); } }