Android开发便签APP

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.com/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.net/major_out/article/details/50656383)

b.新建页面/显示页面:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/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.com/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.com/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.com/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.net/download/qq_38442065/10416733

没有积分的话,在下面留言邮箱,看到后会发过去!

猜你喜欢

转载自blog.csdn.net/qq_38442065/article/details/80309622