一款適合安卓開發(fā)入門者學(xué)習(xí)的 筆記本 APP

前言

本文的內(nèi)容主要是解析Ridder Note APP 的制作流程唆垃,以及代碼的具體實(shí)現(xiàn),若有什么不足之處写妥,還請(qǐng)?zhí)岢鼋ㄗh鸳粉,附上這個(gè) APP 的 Github 地址 Ridder Note 歡迎大家 star 和 fork.

Ridder Note可實(shí)現(xiàn)功能:

[note的增刪改查]

[note分享到QQ WECHAT]

[note備份到服務(wù)器]

3.png

本文的主要內(nèi)容

  • 查詢note的實(shí)現(xiàn)(litepal+sqlite)
  • StarNote和 UnStarNote切換的實(shí)現(xiàn)(Broadcast)
  • 備份日記到服務(wù)器的實(shí)現(xiàn)(接口回調(diào) +handler)

先來(lái)一波Note的展示吧,這款 APP 還是非常精美和優(yōu)雅的

  • 增刪查改note的效果
1.gif
  • StarNote和 UnStarNote切換 上翻下翻記事 清空記事后服務(wù)器端恢復(fù)記事的效果


    2.gif

一集畅、日記查詢的實(shí)現(xiàn)

1近弟、利用litepal建立表

LitePal是一款開源的Android數(shù)據(jù)庫(kù)框架,采用對(duì)象關(guān)系映射(ORM)模式挺智,將常用的數(shù)據(jù)庫(kù)功能進(jìn)行封裝祷愉,可以不用寫一行SQL語(yǔ)句就可以完成創(chuàng)建表、增刪改查的操作。
相關(guān)教程可以參見(jiàn)鏈接litepal

<?xml version="1.0" encoding="utf-8"?>
<litepal>
    <dbname value="Note"></dbname>
    <version value="1"></version>
    <list>
        <mapping class="com.tomridder.ridder_note.bean.Note"></mapping>
    </list>
</litepal>

litePal增刪改已經(jīng)非常簡(jiǎn)單了二鳄,這里就介紹下最復(fù)雜的查詢赴涵。

2、按關(guān)鍵字查詢note的實(shí)現(xiàn)

                String key=starEtSearch.getText().toString();
                notes=querylikeStarNotes(key);
                recycleViewStarNoteAdapter =new RecycleViewStarNoteAdapter(R.layout.star_note,notes);
                recycleViewStarNoteAdapter.setOnItemChildClickListener(StarNoteFragment.this);
                starNotesRecyclerView.setAdapter(recycleViewStarNoteAdapter);   
    private List<Note> querylikeStarNotes(String key)
    {
        List<Note> notes=DataSupport.where("(title like ? or content like ?) and  star = ? ","%"+key+"%","%"+key+"%",1+"").find(Note.class);
        Log.i("note","note size = "+ notes.size());
        return notes;

    }

在querylikeStarNotes函數(shù)中查詢title content中包含字符串key的notes订讼,再傳給recycleViewStarNoteAdapter髓窜,starNotesRecyclerView重新setAdapter。

3欺殿、上翻下翻查詢note

                Note note=getTheNextUnStarNote(oldNote);
                noteShowTitle.setText(note.getTitle());
                noteShowContent.setText(note.getContent());
                noteShowTime.setText(DateFormat.format("MM-dd HH:mm:ss",note.getDate()).toString());
                oldNote=note;
public static Note getTheNextUnStarNote(Note oldNote)
    {
        Note note;
        Cursor c= DataSupport.findBySQL("select * from Note " +
                "where  star =?",String.valueOf(oldNote.getStar()));
        while(c.moveToNext())
        {
            Log.i("note","title ="+oldNote.getTitle()+"content ="+oldNote.getContent()+"date ="+String.valueOf(oldNote.getDate())+
                    "star = "+String.valueOf(oldNote.getStar()));
            String title2=c.getString(c.getColumnIndex("title"));
            String content2=c.getString(c.getColumnIndex("content"));
            if(title2.equals(oldNote.getTitle())&&content2.equals(oldNote.getContent()))
            {
                break;
            }
        }

        if(  c.moveToNext()==true)
        {
            String title2 = c.getString(c.getColumnIndex("title"));
            String content2 = c.getString(c.getColumnIndex("content"));
            long date2 = c.getLong(c.getColumnIndex("date"));
            int star2 = c.getInt(c.getColumnIndex("star"));
            note = new Note(title2, content2, date2, star2);
            Log.i("note","moveToPrevious"+"title ="+note.getTitle()+"content ="+note.getContent()+"date ="+String.valueOf(note.getDate())+
                    "star = "+String.valueOf(note.getStar()));
        }
        else
        {
            c.moveToFirst();
            String title2 = c.getString(c.getColumnIndex("title"));
            String content2 = c.getString(c.getColumnIndex("content"));
            long date2 = c.getLong(c.getColumnIndex("date"));
            int star2 = c.getInt(c.getColumnIndex("star"));
            note = new Note(title2, content2, date2, star2);
            Log.i("note","moveToLast"+"title ="+note.getTitle()+"content ="+note.getContent()+"date ="+String.valueOf(note.getDate())+
                    "star = "+String.valueOf(note.getStar()));
        }
        return note;
    }

litePal沒(méi)有查詢上一條數(shù)據(jù)的API寄纵,所以這里還是用了sqlite。

getTheNextUnStarNote函數(shù)中用while循環(huán)定位到當(dāng)前note所在的游標(biāo)位置脖苏,找到后跳出循環(huán)程拭。

接著游標(biāo)下移一位,返回所在位置的note帆阳。如果當(dāng)前游標(biāo)已經(jīng)在最后一位哺壶,則將游標(biāo)移到第一位,返回note蜒谤。

接著分別setText即可山宾,不要忘了將返回的note賦值給oldNote,用于下次查詢鳍徽。

二资锰、StarNote和 UnStarNote切換的實(shí)現(xiàn)

            case R.id.iv_star2:
                note=(Note)adapter.getData().get(position);
                Note note1=new Note();
                note1.setStar(2);
                int result1=note1.updateAll("title = ? and content = ? and " +
                                "date = ? and star = ?",note.getTitle(),note.getContent()
                        ,String.valueOf(note.getDate()),String.valueOf(note.getStar()));
                Log.i("note","result1 "+result1);
                if(result1>0)
                {
                    recycleViewStarNoteAdapter.remove(position);
                }
                intent=new Intent("com.tomridder.UnStarNote");
                getContext().sendBroadcast(intent);
                break;
    class UnStarChangeReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            List<Note> unStarNotes=QueryUnStarNotes();
            recycleViewUnStarNoteAdapter =new RecycleViewUnStarNoteAdapter(R.layout.unstar_note,unStarNotes);
            recycleViewUnStarNoteAdapter.setOnItemChildClickListener(UnStarNoteFragment.this);
            unStarNotesRecyclerView.setAdapter(recycleViewUnStarNoteAdapter);
        }
    }

在從StarNote到UnStarNote的轉(zhuǎn)換中,首先在數(shù)據(jù)庫(kù)中更改star的值從1到2阶祭。

如果更改成功從當(dāng)前的StarNoteFragment中的recycleView中移除當(dāng)前的note绷杜。

接著發(fā)出一條名字為"com.tomridder.UnStarNote"的廣播。

UnStarFragment中會(huì)注冊(cè)這條廣播濒募,如果接收到則會(huì)刷新UnStarNoteFragment的recycleView鞭盟。從而完成整個(gè)效果。

三瑰剃、備份日記到服務(wù)器的實(shí)現(xiàn)

1齿诉、更改日記同步到服務(wù)器端的實(shí)現(xiàn)

                 final String SERVER_URL="http://coder.struggling-bird.cn:8761/weixin/note/update?";
                 final String data="title="+title+"&date="+longToString(System.currentTimeMillis())+"&content="+content+"&star="+oldNote.getStar()
                         +"&oldTitle="+oldNote.getTitle()+"&oldDate="+longToString(oldNote.getDate())+"&oldContent="+oldNote.getContent()
                         +"&oldStar="+oldNote.getStar();
                 new Thread()
                 {
                     @Override
                     public void run() {
                         super.run();
                         OkHttpClient okHttpClient=new OkHttpClient.Builder()
                                 .connectTimeout(10, TimeUnit.SECONDS)
                                 .writeTimeout(10,TimeUnit.SECONDS)
                                 .readTimeout(10,TimeUnit.SECONDS)
                                 .build();
                         Request request=new Request.Builder()
                                 .url(SERVER_URL+data)
                                 .build();
                         try
                         {
                             Response response=okHttpClient.newCall(request).execute();
                             if(response.isSuccessful())
                             {
                                 Log.i("Note",response.body().toString());
                             }else
                             {
                                 Log.i("Note","failed");
                             }
                         }catch (IOException e)
                         {
                             e.printStackTrace();
                         }

                     }
                 }.start();

這里只需要用使用okhttp,將SERVER_URL和參數(shù)data(包含oldNote的 title,content,date,star的newNote的title,content,date,star )拼接起來(lái)晌姚,
作為Request的url參數(shù)粤剧,最后發(fā)起請(qǐng)求即可。

2挥唠、 從服務(wù)器端恢復(fù)日記到本地的實(shí)現(xiàn)

public static void ParseDataWithJsonObject(String response)
    {
        try
        {
            JSONArray notes=new JSONArray(response);
            DataSupport.deleteAll(Note.class);
            for(int i=0;i<notes.length();i++)
            {
                JSONObject note=notes.getJSONObject(i);
                String title=note.getString("title");
                String content=note.getString("content");
                String date=note.getString("date");
                int star=note.getInt("star");
                Note note1=new Note(title,content,stringToLong(date),star);
                note1.save();
            }
        }catch (JSONException e)
        {
            e.printStackTrace();
        }
    }
new Thread()
               {
                   @Override
                   public void run() {
                       super.run();
                       OkHttpClient okHttpClient=new OkHttpClient.Builder()
                               .connectTimeout(10, TimeUnit.SECONDS)
                               .readTimeout(10,TimeUnit.SECONDS)
                               .writeTimeout(10,TimeUnit.SECONDS)
                               .build();
                       Request request=new Request.Builder()
                               .url(SERVER_URL)
                               .build();
                       try
                       {
                           Response response=okHttpClient.newCall(request).execute();
                           if(response.isSuccessful())
                           {
                               String data=response.body().string();
                               ParseDataWithJsonObject(data);
                               Intent intent=new Intent("com.tomridder.StarNote");
                               sendBroadcast(intent);
                               Intent intent2=new Intent("com.tomridder.UnStarNote");
                               sendBroadcast(intent2);
                           }
                       }catch (IOException e)
                       {
                           e.printStackTrace();
                       }
                   }
               }.start();

首先向SERVER_URL發(fā)起請(qǐng)求抵恋,得到response后,在ParseDataWithJsonObject中將resposne的JSON串轉(zhuǎn)成jsonArray宝磨,

接著利用for循環(huán)取出jsonArray中的jsonObject弧关,轉(zhuǎn)換成note對(duì)象盅安,一個(gè)個(gè)寫到數(shù)據(jù)庫(kù)中。

    public interface Callback1
    {
        void fresh();
    }

 Handler handler=new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case 1:
                    List<Note> unStarNotes=QueryUnStarNotes();
                    recycleViewUnStarNoteAdapter =new RecycleViewUnStarNoteAdapter(R.layout.unstar_note,unStarNotes);
                    recycleViewUnStarNoteAdapter.setOnItemChildClickListener(UnStarNoteFragment.this);
                    unStarNotesRecyclerView.setAdapter(recycleViewUnStarNoteAdapter);
                    Log.i("Note","Received Un");
                    break;


            }
        }
    };
    @Override
    public void fresh() {
        Message message=new Message();
        message.what=1;
        handler.sendMessage(message);
        Log.i("Note","Send Un ");
    }

接下來(lái)MainNote Activity和 UnStarFragment 梯醒, StarFragment的通信方式我采取了接口回調(diào)的方式宽堆。

MainNote含有Callback對(duì)象的List集合,UnStarFragment 茸习, StarFragment分別集成自Callback接口畜隶,并實(shí)現(xiàn)fresh()方法。

最后由于不能在子線程 函數(shù)fresh()中刷新recyclerView号胚,我采用了handler來(lái)更改view籽慢。

這樣最后效果實(shí)現(xiàn)。

以上便是我寫這個(gè) APP 的具體實(shí)現(xiàn)思路猫胁,以及踩過(guò)的一些坑箱亿,記錄下來(lái),給大家看看弃秆,最后附上這個(gè) APP 的 Github 地址 Ridder Note 歡迎大家 star 和 fork届惋,如果有什么想法或者建議,非常歡迎大家來(lái)討論


猜你喜歡

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末菠赚,一起剝皮案震驚了整個(gè)濱河市脑豹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌衡查,老刑警劉巖瘩欺,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異拌牲,居然都是意外死亡俱饿,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門塌忽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)拍埠,“玉大人,你說(shuō)我怎么就攤上這事土居⌒蹬模” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵装盯,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我甲馋,道長(zhǎng)埂奈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任定躏,我火速辦了婚禮账磺,結(jié)果婚禮上芹敌,老公的妹妹穿的比我還像新娘。我一直安慰自己垮抗,他們只是感情好氏捞,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冒版,像睡著了一般液茎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辞嗡,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天捆等,我揣著相機(jī)與錄音,去河邊找鬼续室。 笑死栋烤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的挺狰。 我是一名探鬼主播明郭,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼丰泊!你這毒婦竟也來(lái)了薯定?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤趁耗,失蹤者是張志新(化名)和其女友劉穎沉唠,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體苛败,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡满葛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了罢屈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘀韧。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖缠捌,靈堂內(nèi)的尸體忽然破棺而出锄贷,到底是詐尸還是另有隱情,我是刑警寧澤曼月,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布谊却,位于F島的核電站,受9級(jí)特大地震影響哑芹,放射性物質(zhì)發(fā)生泄漏炎辨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一聪姿、第九天 我趴在偏房一處隱蔽的房頂上張望碴萧。 院中可真熱鬧乙嘀,春花似錦、人聲如沸破喻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)曹质。三九已至婴噩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咆繁,已是汗流浹背讳推。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留玩般,地道東北人银觅。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像坏为,于是被迫代替她去往敵國(guó)和親究驴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容