1.设计知识:
framelayout、floatingactionbutton、menu、listview、adapter、sqlite
2.开发工具:
Android Studio 3.1.1
工程目录:
3.界面设计:
a.主界面:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/layout_listview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/add_note"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="15dp"
android:src="@mipmap/add_picture"
/>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
页面如下:
注意:
当我们使用floatingactionbutton时,一定是要在framelayout布局之内放置listview和floatingactionbutton,如果不是这样,会因为布局的重合而导致floatingactionbutton被覆盖掉,而使用framelayout页面重合时只是重合布局之内的控件,而不会覆盖前面的布局的东西(具体原因请查看博客:https://blog.csdn/major_out/article/details/50656383)
b.新建页面/显示页面:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="10dp"
>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/new_title"
android:textSize="24dp"
android:textColor="@color/colorPrimaryDark"
/>
<EditText
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
android:hint="@string/new_settitle"
android:ems="10"
android:textSize="24dp"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/new_content"
android:textColor="@color/colorPrimaryDark"
android:textSize="24dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp">
<EditText
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="top"
android:hint="@string/new_inputcontent"
android:textSize="24dp"
android:background="@null"/>
</LinearLayout>
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/finish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="15dp"
android:src="@mipmap/duigou"
/>
</FrameLayout>
</LinearLayout>
页面如下:
c.菜单:
主界面中放置的菜单:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android/apk/res/android">
<item
android:id="@+id/menu_newnote"
android:title="@string/menu_newnote"
/>
<item
android:id="@+id/menu_exit"
android:title="@string/menu_exit"
/>
</menu>
新建/展示页面中菜单:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android/apk/res/android">
<item
android:id="@+id/new_share"
android:title="@string/menu_share"
/>
</menu>
d.listview子项布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="100dp">
<TextView
android:id="@+id/list_title"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:gravity="center_vertical"
android:layout_marginLeft="20dp"
android:textSize="20dp"/>
<TextView
android:id="@+id/list_time"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:textSize="15dp"
/>
</LinearLayout>
e.resource中string使用:
<resources>
<string name="app_name">便签</string>
<string name="new_title">标题:</string>
<string name="new_settitle">请输入便签标题~</string>
<string name="new_content">内容:</string>
<string name="new_inputcontent">请输便签入内容~</string>
<string name="menu_newnote">新建</string>
<string name="menu_exit">退出</string>
<string name="menu_share">分享便签</string>
</resources>
4.java代码:
a.首先我们的数据要存放在SQLite数据库中,那么我们需要建立一个数据表,首先考虑要建立一个怎么样的表,我的想法是建立一个四个字段的数据表,分别为id、标题、内容、时间,那么问题来了,我们怎么建表呢,幸运的是在android中已经封装好一个帮助类SQLiteOpenHelper,这是一个抽象类,便于我们管理SQLite数据库的抽象类,我们要使用这个帮助类就先得创建一个类去继承它,代码如下:
package presenter;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
//
public class MyOpenHelper extends SQLiteOpenHelper {
public MyOpenHelper(Context context) {
super(context, "mydate", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table mybook(" + //表名设置为mybook
"ids integer PRIMARY KEY autoincrement," + //设置id自增
"title text," + //设置标题为文本类型
"content text," + //设置内容为文本类型
"times text)"); //设置时间为文本类型
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
b.我们现在已经知道我们的数据表中存放的是什么数据,那么我们现在就可以去新建一个类,这个类的属性就是我们要存放的数据,这也就是相当于建立一个模型,代码如下:
package model;
public class Data {
private String title; //标题
private String content; //内容
private String times; //时间
private int ids; //编号
public Data(String ti,int id,String con ,String time){
this.ids=id;
this.title=ti;
this.content=con;
this.times=time;
}
public Data(String ti,String con,String time){
this.title=ti;
this.content=con;
this.times=time;
}
public Data(int i,String ti,String time){
this.ids=i;
this.title=ti;
this.times=time;
}
public Data(String ti,String con){
this.title=ti;
this.content=con;
}
public int getIds() {
return ids;
}
public String getTitle() {
return title;
}
public String getContent() {
return content;
}
public String getTimes() {
return times;
}
}
我们可以看到这里面有对Data构造方法的重载,这都是为了后面其他类的调用。
c.我们的便签要具有长按删除,编辑,新建的功能是吧,那么我们就肯定要对数据库中的数据进行增删改查的操作,这里我们可以新建一个类,把增删改查等方法都放在里面,代码如下:
package presenter;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.util.ArrayList;
import model.Data;
public class MyDatabase {
Context context;
MyOpenHelper myOpenHelper;
SQLiteDatabase mydatabase;
public MyDatabase(Context context){
this.context = context;
myOpenHelper = new MyOpenHelper(context);
}
public ArrayList<Data> getarray(){ //获取listview中要显示的数据
ArrayList<Data> arr = new ArrayList<Data>();
ArrayList<Data> arr1 = new ArrayList<Data>();
mydatabase = myOpenHelper.getWritableDatabase();
Cursor cursor = mydatabase.rawQuery("select ids,title,times from mybook",null);
cursor.moveToFirst();
while(!cursor.isAfterLast()){
int id = cursor.getInt(cursor.getColumnIndex("ids"));
String title = cursor.getString(cursor.getColumnIndex("title"));
String times = cursor.getString(cursor.getColumnIndex("times"));
Data data = new Data(id, title, times);
arr.add(data);
cursor.moveToNext();
}
mydatabase.close();
for (int i = arr.size(); i >0; i--) {
arr1.add(arr.get(i-1));
}
return arr1;
}
public Data getTiandCon(int id){ //获取要修改数据(就是当选择listview子项想要修改数据时,获取数据显示在新建页面)
mydatabase = myOpenHelper.getWritableDatabase();
Cursor cursor=mydatabase.rawQuery("select title,content from mybook where ids='"+id+"'" , null);
cursor.moveToFirst();
String title=cursor.getString(cursor.getColumnIndex("title"));
String content=cursor.getString(cursor.getColumnIndex("content"));
Data data=new Data(title,content);
mydatabase.close();
return data;
}
public void toUpdate(Data data){ //修改表中数据
mydatabase = myOpenHelper.getWritableDatabase();
mydatabase.execSQL(
"update mybook set title='"+ data.getTitle()+
"',times='"+data.getTimes()+
"',content='"+data.getContent() +
"' where ids='"+ data.getIds()+"'");
mydatabase.close();
}
public void toInsert(Data data){ //在表中插入新建的便签的数据
mydatabase = myOpenHelper.getWritableDatabase();
mydatabase.execSQL("insert into mybook(title,content,times)values('"
+ data.getTitle()+"','"
+data.getContent()+"','"
+data.getTimes()
+"')");
mydatabase.close();
}
public void toDelete(int ids){ //在表中删除数据
mydatabase = myOpenHelper.getWritableDatabase();
mydatabase.execSQL("delete from mybook where ids="+ids+"");
mydatabase.close();
}
}
d.那么我们怎么样把数据放在放在listview中,方便在主页面显示呢,那么我们这里就需要为listview设一个适配器,代码如下:
package presenter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.example.gahui.take_notes.R;
import java.util.ArrayList;
import model.Data;
public class MyAdapter extends BaseAdapter {
LayoutInflater inflater;
ArrayList<Data> array;
public MyAdapter(LayoutInflater inf,ArrayList<Data> arry){
this.inflater=inf;
this.array=arry;
}
@Override
public int getCount() {
return array.size();
}
@Override
public Object getItem(int position) {
return array.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) { //代码块中包含了对listview的效率优化
ViewHolder vh;
if(convertView==null){
vh=new ViewHolder();
convertView=inflater.inflate(R.layout.list_item,null);//加载listview子项
vh.tv1=(TextView) convertView.findViewById(R.id.list_title);
vh.tv2=(TextView) convertView.findViewById(R.id.list_time);
convertView.setTag(vh);
}
vh=(ViewHolder) convertView.getTag();
vh.tv1.setText(array.get(position).getTitle());
vh.tv2.setText(array.get(position).getTimes());
return convertView;
}
class ViewHolder{ //内部类,对控件进行缓存
TextView tv1,tv2;
}
}
e.这些工作做完之后,我们就可以编辑主页面对应的java代码了:
package com.example.gahui.take_notes;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import java.util.ArrayList;
import model.Data;
import presenter.MyAdapter;
import presenter.MyDatabase;
public class MainActivity extends AppCompatActivity {
ListView listView;
FloatingActionButton floatingActionButton;
LayoutInflater layoutInflater;
ArrayList<Data> arrayList;
MyDatabase myDatabase;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.layout_listview);
floatingActionButton = (FloatingActionButton)findViewById(R.id.add_note);
layoutInflater = getLayoutInflater();
myDatabase = new MyDatabase(this);
arrayList = myDatabase.getarray();
MyAdapter adapter = new MyAdapter(layoutInflater,arrayList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { //点击一下跳转到编辑页面(编辑页面与新建页面共用一个布局)
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getApplicationContext(),New_note.class);
intent.putExtra("ids",arrayList.get(position).getIds());
startActivity(intent);
MainActivity.this.finish();
}
});
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { //长按删除
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
new AlertDialog.Builder(MainActivity.this) //弹出一个对话框
//.setTitle("确定要删除此便签?")
.setMessage("确定要删除此便签?")
.setNegativeButton("取消",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setPositiveButton("确定",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
myDatabase.toDelete(arrayList.get(position).getIds());
MyAdapter myAdapter = new MyAdapter(layoutInflater,arrayList);
listView.setAdapter(myAdapter);
}
})
.create()
.show();
return true;
}
});
floatingActionButton.setOnClickListener(new View.OnClickListener() { //点击悬浮按钮时,跳转到新建页面
@Override
public void onClick(View v) {
Intent intent=new Intent(getApplicationContext(),New_note.class);
startActivity(intent);
MainActivity.this.finish();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_lo,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.menu_newnote:
Intent intent = new Intent(getApplicationContext(),New_note.class);
startActivity(intent);
MainActivity.this.finish();
break;
case R.id.menu_exit:
MainActivity.this.finish();
break;
default:
break;
}
return true;
//return false;????是用哪个true or false?
}
}
f.接着是新建页面/编辑页面的代码:
package com.example.gahui.take_notes;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import java.text.SimpleDateFormat;
import java.util.Date;
import model.Data;
import presenter.MyDatabase;
public class New_note extends AppCompatActivity {
EditText ed_title;
EditText ed_content;
FloatingActionButton floatingActionButton;
MyDatabase myDatabase;
Data data;
int ids;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new_note);
ed_title = (EditText)findViewById(R.id.title);
ed_content = (EditText)findViewById(R.id.content);
floatingActionButton = (FloatingActionButton)findViewById(R.id.finish);
myDatabase = new MyDatabase(this);
Intent intent = this.getIntent();
ids = intent.getIntExtra("ids",0);
if (ids != 0){
data = myDatabase.getTiandCon(ids);
ed_title.setText(data.getTitle());
ed_content.setText(data.getContent());
}
floatingActionButton.setOnClickListener(new View.OnClickListener() {//为悬浮按钮设置监听事件
@Override
public void onClick(View v) {
isSave();
}
});
}
@Override
public void onBackPressed() { //重写返回建方法,如果是属于新建则插入数据表并返回主页面,如果是修改,修改表中数据并返回主页面
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");//编辑便签的时间,格式化
Date date = new Date(System.currentTimeMillis());
String time = simpleDateFormat.format(date);
String title = ed_title.getText().toString();
String content = ed_content.getText().toString();
if(ids!=0){
data=new Data(title,ids, content, time);
myDatabase.toUpdate(data);
Intent intent=new Intent(New_note.this,MainActivity.class);
startActivity(intent);
New_note.this.finish();
}
//新建日记
else{
data=new Data(title,content,time);
myDatabase.toInsert(data);
Intent intent=new Intent(New_note.this,MainActivity.class);
startActivity(intent);
New_note.this.finish();
}
}
private void isSave(){ //写一个方法进行调用,如果是属于新建则插入数据表并返回主页面,如果是修改,修改表中数据并返回主页面
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm");
Date date = new Date(System.currentTimeMillis());
String time = simpleDateFormat.format(date);
Log.d("new_note", "isSave: "+time);
String title = ed_title.getText().toString();
String content = ed_content.getText().toString();
if(ids!=0){
data=new Data(title,ids, content, time);
myDatabase.toUpdate(data);
Intent intent=new Intent(New_note.this,MainActivity.class);
startActivity(intent);
New_note.this.finish();
}
//新建日记
else{
data=new Data(title,content,time);
myDatabase.toInsert(data);
Intent intent=new Intent(New_note.this,MainActivity.class);
startActivity(intent);
New_note.this.finish();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.new_lo,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.new_share : //分享功能
Intent intent=new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT,//分享类型设置为文本型
"标题:"+ed_title.getText().toString()+" " +
"内容:"+ed_content.getText().toString());
startActivity(intent);
break;
default:
break;
}
return false;
}
}
4.接下来使用手机测试:
5.存在不足:
界面不够美观,额,就是我懒,,,,,
6.源代码下载地址:
https://download.csdn/download/qq_38442065/10416733
没有积分的话,可用Git Clone :https://github/Gahui-Liao/Take_Notes.git
更多推荐
Android开发便签APP
发布评论