1. 程式人生 > >Android開發--便籤(一)

Android開發--便籤(一)

我的上一篇部落格http://blog.csdn.net/callmesp/article/details/52895630 講的是ListView和RecyclerView,起因就是想開發一個便籤的時候才遇到的問題。在學習了RecyclerView之後呢,在今天上午花了一段時間把這個app寫了出來(水平有限),來與大家分享。

專案地址為

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context="com.example.notes_2.MainActivity"> <RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay" android:id="@+id/aaa"> <android.support
.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout> <android.support.v7.widget.RecyclerView android:layout_below="@+id/aaa" android:id="@+id/recycle" android:layout_width="fill_parent" android:layout_height="match_parent" android:layout_weight="1"> </android.support.v7.widget.RecyclerView> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:src="@android:drawable/ic_menu_add" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" /> </RelativeLayout> </android.support.design.widget.CoordinatorLayout>

前面的AppBarLayout就是建立project時候自動生成的不用去管它,也可以在toolbar上設定一個按鈕來增添一個編輯功能(這個功能還沒實現,目前還沒學會..等實現了再回來寫一個Android開發–便籤(二),有什麼建議的話也可以告訴我)。下面兩個控制元件就是重點了,一個RecyclerView負責顯示資訊和一個FloatingActionButton懸浮的按鈕來觸發增加便籤的事件。不明白的可以看我上一篇部落格這裡就不詳細的說了。
下面是list_item

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.example.notes_2.MainActivity"
    android:orientation="vertical">
<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card_view:cardBackgroundColor="#FFFFB9"
    card_view:cardCornerRadius="10dp"
    card_view:cardPreventCornerOverlap="true"
    card_view:cardUseCompatPadding="true"
    card_view:contentPadding="10dp">
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="10sp"
        android:paddingRight="10sp"
        android:paddingTop="15sp"
        android:singleLine="true"
        android:id="@+id/time" />
    <TextView
        android:id="@+id/content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:paddingLeft="10sp"
        android:paddingRight="10sp"
        android:paddingTop="15sp"
        android:paddingBottom="15sp" />
    </LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>

這裡用了一個CardView

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card_view:cardBackgroundColor="#FFFFB9"
    card_view:cardCornerRadius="10dp"
    card_view:cardPreventCornerOverlap="true"
    card_view:cardUseCompatPadding="true"
    card_view:contentPadding="10dp">

也是一個比較新的控制元件,這是今天才學會的,這裡就是簡單的呼叫一下,也沒什麼好說的,如果有時間的話會深入的研究一下,研究一下各種自定義,然後專門寫一篇部落格。現在,值得注意的一點就是我在裡面嵌套了一個LinearLayout然後才在裡面寫了兩個TextView,為什麼要這樣多此一舉而不是直接就寫兩個TextView呢?這裡其實我一開始也沒加,不過在測試的時候發現兩個TextView重合起來了,我感覺這個CardView就相當於一個改了style改了background的一個FrameLayout,所以要先巢狀然後再使用,總比什麼都要自定義要方便的多了。然後兩個TextView一個用來顯示時間一個顯示內容。
下面就開始上主要的內容了。
DBHelper.java

package com.example.notes_2;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by my on 2016/10/23.
 */
public class DBHelper extends SQLiteOpenHelper {
    private final static String DB_NAME="my.db";
    private final static int DB_VERSION=1;
    private final  static String TABLE_NAME="info";
    private final static String CONTENT="content";
    private final static String TIME="date";
    private final static String ID="_id";
    SQLiteDatabase database=getWritableDatabase();
    public DBHelper(Context context){
        super(context,DB_NAME,null,DB_VERSION);
    }
    //paramSQLiteDatabase.execSQL("create table " + NAME + "(id INTEGER PRIMARY KEY AUTOINCREMENT,title TEXT,date TEXT,content TEXT)");
    @Override
    public void onCreate(SQLiteDatabase database){
        database.execSQL("create table " + TABLE_NAME + "(_id INTEGER PRIMARY KEY AUTOINCREMENT,date TEXT,content TEXT)");
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
    public long insert(String text){
        ContentValues contentValues=new ContentValues();
        contentValues.put("content",text);

        //獲取系統時間
        SimpleDateFormat formatter=new SimpleDateFormat("yy-MM-dd HH:mm");
        Date curDate =  new Date(System.currentTimeMillis());
        String time=formatter.format(curDate);


        contentValues.put("date",time);
        long row=database.insert(TABLE_NAME,null,contentValues);
        Log.e("time:", time);
        Log.e("content", text);
        return row;
    }
    public void update(int _id,String text){
        ContentValues contentValues=new ContentValues();
        contentValues.put("content",text);
        database.update(TABLE_NAME,contentValues,ID+"=?",new String[]{Integer.toString(_id)});
    }
    public void delete(int _id){
        database.delete(TABLE_NAME, ID + "=?", new String[]{Integer.toString(_id)});
    }
    public Cursor select(){
        Cursor cursor=database.query(TABLE_NAME,null,null,null,null,null,null);
        return cursor;
    }
}
/*
public long add(SQLiteDatabase paramSQLiteDatabase, Notepad paramNotepad) {
        ContentValues localContentValues = new ContentValues();
        localContentValues.put("title", paramNotepad.getTitle());
        localContentValues.put("date", paramNotepad.getdata());
        localContentValues.put("content", paramNotepad.getContent());
        long l = paramSQLiteDatabase.insert(table, null, localContentValues);
        paramSQLiteDatabase.close();
        return l;
    }

 */

這個就是這個專案的核心了,一個數據庫幫助類,這裡用的是SQLite一個輕量級資料庫,後面我會專門詳細的寫一篇部落格來講它的。這裡先簡單的認識一下就可以。它有幾個引數,也是在構造的時候需要的,資料庫名字,資料庫版本,表名,id,還有就是表裡面的內容了,可以隨意設定。

SQLiteDatabase database=getWritableDatabase();

這裡用了一個基礎類獲取讀寫資料庫的許可權,否則是會閃退的。然後就是對它的各種功能的重寫,新增,刪除,插入,更新等等。放入內容的時候用了ContentValues,一個鍵值對。比如contentValues.put(“content”,text);就是把text的內容賦予表裡面的“content”這一列。別的也沒什麼了。

然後是寫一個介面卡adpter來適配我們的RecyclerView。

package com.example.notes_2;

import android.content.Context;
import android.database.Cursor;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

/**
 * Created by my on 2016/10/23.
 */
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.MyViewHolder>  {
    private List<String> mDatas;
    private Context mContext;
    private LayoutInflater inflater;
    private Cursor mmcursor;
    private DBHelper mmDbhelper;
    int k=0;
    private OnItemClickListener mOnItemClickListener;
    public MyRecyclerAdapter(Context context,Cursor cursor,DBHelper dbHelper){
        this.mContext=context;
        this.mmcursor=cursor;
        this.mmDbhelper=dbHelper;
        inflater= LayoutInflater. from(mContext);
    }
    @Override
    public int getItemCount() {
        return mmcursor.getCount();
    }

    //填充onCreateViewHolder方法返回的holder中的控制元件
    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        mmcursor.moveToPosition(mmcursor.getCount()-position-1);
        holder.tv_time.setText(mmcursor.getString(1));
        holder.tv_content.setText(mmcursor.getString(2));
        //實現介面
        if( mOnItemClickListener!= null){
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mOnItemClickListener.onClick(position);
                }
            });
        }
    }

    //重寫onCreateViewHolder方法,返回一個自定義的ViewHolder
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = inflater.inflate(R.layout.list_item,parent, false);
        MyViewHolder holder= new MyViewHolder(view);
        return holder;
    }

    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tv_time;
        TextView tv_content;
        public MyViewHolder(View view) {
            super(view);
            tv_time=(TextView)view.findViewById(R.id.time);
            tv_content=(TextView) view.findViewById(R.id.content);
        }
    }
    public interface OnItemClickListener{
        void onClick(int position);
    }
    public void setOnItemClickListener(OnItemClickListener onItemClickListener ){
        this. mOnItemClickListener=onItemClickListener;
    }
}

這裡用到了cursor來適配這個DBHelper,後面講SQLite的時候也會詳細講,這裡只需要將它理解成指標就好了,然後從表裡面取值的時候,用cursor.moveToPosition(int position);移動到那一行;然後cursor.getString(int x));移動到那一列,列的順序就是atabase.execSQL(“create table ” + TABLE_NAME + “(_id INTEGER PRIMARY KEY AUTOINCREMENT,date TEXT,content TEXT)”);引號裡面自己定義的順序。從0開始。
接下來就是我們的MainActivity了。

package com.example.notes_2;

import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private ListView listView;
    private Cursor cursor;
    private DBHelper dbHelper;
    private RecyclerView recyclerView;
    private MyRecyclerAdapter adapter;
    private int _id=0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.revycle_new);

        dbHelper=new DBHelper(this);
        cursor=dbHelper.select();
        recyclerView=(RecyclerView)findViewById(R.id.recycle);
        adapter=new MyRecyclerAdapter(this,cursor,dbHelper);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        GridLayoutManager gridLayoutManager=new GridLayoutManager(this,2);
        StaggeredGridLayoutManager staggeredGridLayoutManager= new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
        //設定佈局管理器
        recyclerView.setLayoutManager(staggeredGridLayoutManager);
        //設定為垂直佈局,這也是預設的
        layoutManager.setOrientation(OrientationHelper.VERTICAL);
        //設定Adapter
        recyclerView.setAdapter(adapter);
        Log.e("0","getcount:"+adapter.getItemCount());
        //設定增加或刪除條目的動畫
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        adapter.setOnItemClickListener(new MyRecyclerAdapter.OnItemClickListener() {
            @Override
            public void onClick(int position) {
                cursor.moveToPosition(cursor.getCount()-1-position);
                _id=cursor.getInt(0);
                Intent intent=new Intent(MainActivity.this,Modify.class);
                intent.putExtra("id",_id);
                intent.putExtra("data",cursor.getString(2));//getString(1)顯示cursor該列的內容
                Log.e("0","MainActivity to modify_contetn:"+cursor.getString(2));
                Log.e("0","id:"+_id);
                startActivity(intent);
                finish();
            }
        });




        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this,Content.class);
                startActivity(intent);
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

邏輯很清晰就不用細講了。還有就是點選增加便籤的Activity還有點進便籤的Activity下面把程式碼貼出來。
content.java

package com.example.notes_2;

import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by my on 2016/10/23.
 */
public class Content extends Activity implements View.OnClickListener {
    private Button okButton,cancleButton;
    private EditText contentWrite;
    private DBHelper dbHelper;
    private Cursor cursor;
    private int _id=0;
    private Time time;
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content);
        init();
    }
    private void init(){
        dbHelper=new DBHelper(this);
        cursor=dbHelper.select();
        okButton = (Button) findViewById(R.id.btn_ok);
        cancleButton = (Button) findViewById(R.id.btn_cancle);
        contentWrite = (EditText) findViewById(R.id.et_content);
        okButton.setOnClickListener(this);
        cancleButton.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_ok:
                addData() ;
                Intent intent = new Intent(this,MainActivity.class);
                startActivity(intent);
                finish();
                break;

            case R.id.btn_cancle:
                Intent intent1 = new Intent(this,MainActivity.class);
                startActivity(intent1);
                finish();
                break;
        }
    }
    private void addData(){
        if (contentWrite.getText().toString().equals("")){
            Toast.makeText(Content.this,"內容不能為空",Toast.LENGTH_SHORT).show();
        }else{

            dbHelper.insert(contentWrite.getText().toString());
            cursor.requery();
            contentWrite.setText("");
            _id=0;
        }
    }
    @Override
    public boolean onKeyDown(int keycode,KeyEvent event){
        if (keycode==KeyEvent.KEYCODE_BACK){
        Intent intent = new Intent(this,MainActivity.class);
        startActivity(intent);
        finish();return true;}else{
            return super.onKeyDown(keycode,event);
        }


    }
}

效果圖這裡寫圖片描述

modify.java

package com.example.notes_2;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

/**
 * Created by my on 2016/10/23.
 */
public class Modify extends Activity implements View.OnClickListener {
    private EditText et_show;
    private Button updateButton, deleteButton, backButton;
    private DBHelper dbHelper;
    private Cursor cursor;
    private int id;

    @Override
    protected void onCreate(Bundle s) {
        super.onCreate(s);
        setContentView(R.layout.modify);
        init();
    }

    private void init() {
        et_show = (EditText) findViewById(R.id.et_modify);
        Intent intent = getIntent();
        String data = intent.getStringExtra("data");
        id = intent.getIntExtra("id", id);
        et_show.setText(data);
        dbHelper = new DBHelper(this);
        cursor = dbHelper.select();
        updateButton = (Button) findViewById(R.id.btn_update);
        deleteButton = (Button) findViewById(R.id.btn_delete);
        backButton = (Button) findViewById(R.id.btn_back);
        updateButton.setOnClickListener(this);
        deleteButton.setOnClickListener(this);
        backButton.setOnClickListener(this);
    }

    public void updateData() {
        if (id == 0) {
            Toast.makeText(Modify.this, "內容不能為空", Toast.LENGTH_SHORT).show();
        } else {
            dbHelper.update(id, et_show.getText().toString());
            cursor.requery();
            id = 0;
        }
    }
    public void deleteData(){
        if (id==0){
            Toast.makeText(Modify.this, "內容不能為空", Toast.LENGTH_SHORT).show();
        }else{
            dbHelper.delete(id);
            cursor.requery();
            id=0;
        }
    }
    @Override
    public void onClick(View arg0) {
        switch (arg0.getId()) {
            case R.id.btn_update:
                updateData();
                Intent intent1 = new Intent(this,MainActivity.class);
                startActivity(intent1);
                finish();
                break;

            case R.id.btn_delete:
                deleteData();
                Intent intent = new Intent(this,MainActivity.class);
                startActivity(intent);
                finish();
                break;
            case R.id.btn_back:
                Intent intent2 = new Intent(this,MainActivity.class);
                startActivity(intent2);
                finish();
                break;
        }

    }
    @Override
    public boolean onKeyDown(int keycode,KeyEvent event){
        if (keycode==KeyEvent.KEYCODE_BACK){
            Intent intent = new Intent(this,MainActivity.class);
            startActivity(intent);
            finish();return true;}else{
            return super.onKeyDown(keycode,event);
        }


    }
}

這裡寫圖片描述
還有這兩個activity的xml。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        >
        <Button
            android:id="@+id/btn_ok"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="完成"
            android:background="@color/colorPrimary"
            />

        <TextClock
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:format12Hour="yyyy年dd月MM日 HH:mm"
            />
        <Button
            android:id="@+id/btn_cancle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="取消"
            android:background="@color/colorPrimary"
            />
    </LinearLayout>

    <EditText
        android:id="@+id/et_content"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:hint="Type something here"
        />

</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:id="@+id/xx"
        >
        <Button
            android:id="@+id/btn_back"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="返回"
            android:background="@color/colorPrimary" />
        <TextClock
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:format12Hour="yy/dd/MM-HH:mm"
            />
        <Button
        android:id="@+id/btn_delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="刪除"
        android:layout_alignParentRight="true"
        android:background="@color/colorPrimary" />


    </RelativeLayout>
    <Button
        android:id="@+id/btn_update"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="儲存"
        android:layout_alignParentBottom="true"
        android:background="@color/colorPrimary"
        />
    <EditText
        android:id="@+id/et_modify"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/xx"
        />


</RelativeLayout>

這樣就實現了一個簡易的便籤了。 與大家分享。