#土豆记事#教你开发Android App之 —— 真的开始写App了

基础界面

咱们要开发的App界面以下
clipboard.pnghtml

  1. 有一个title
  2. 一个列表
  3. 右下角一个按钮
  1. title 能够用系统自带的ActionBar实现(Lollipop以上为Toolbar)。
  2. 下面的列表能够用ListView或者android-support-compact-v7提供的新的RecyclerView。展现一个列表。
  3. 按钮可使用普通的Button,我这里为了符合Material Design规范,使用了FloatingActionButton,没什么不一样,只是展现出来的样式不同而已。

整个界面就这么简单。android

咱们能够看到Toolbar如下的部分是列表和按钮,它们的排列不是属于线性排列,因此咱们就想到用RelativeLayout布局 —— 列表占满空间,而按钮存在容器的右下角。
咱们的布局文件就以下:git

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <org.lifefortheorc.tudounotepad.widget.EmptyRecyclerView
        android:id="@+id/recycler_note"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TextView
        android:id="@+id/tv_empty"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/empty"
        android:gravity="center"
        android:layout_centerInParent="true" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentBottom="true"
        android:layout_marginEnd="@dimen/activity_horizontal_margin"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:src="@drawable/ic_add" />

</RelativeLayout>

这其中的tv_empty是咱们用来作一个列表空内容的提醒的,触发的结果以下
当列表不为空时隐藏,当列表为空时就显示
clipboard.pnggithub

关于列表

无论是ListView仍是RecylerView,若是你熟悉iOS开发的话,会理解item重用的机制——Android为了省资源,只会建立一屏幕的item,若是你的列表项目数目大于一个屏幕,当你滚下列表时,系统会把顶上的item回收,在回调函数里提供给你从新使用,而后从新在底部显示出来,这样的好处是你建立的item不论你实际数据的大小,它至多只建立一个屏幕多的数量,能节省资源。数据库

列表、子视图和数据之间的交互使用了适配器模式,在Adapter中把你的数据渲染到item view上,而后应用给父视图。
关于ListView的介绍,请看传送门:http://developer.android.com/guide/topics/ui/layout/listview.htmlide

若是你看懂了ListView,那么RecylerView只是对其的一种优化,使用了更多的自定义的属性和更方便自由的布局管理系统。函数

我这里使用了RecylerView,咱们来看下适配器的源码布局

public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.ViewHolder> {

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");

    private Context mContext;
    private List<NoteModel> noteList;

    public NoteAdapter(Context ctx) {
        this.noteList = new ArrayList<>();
        this.mContext = ctx;
    }

    public void setNoteList(List<NoteModel> noteList) {
        //设置数据
        this.noteList.clear();
        this.noteList.addAll(noteList);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        View view = layoutInflater.inflate(R.layout.item_note, viewGroup, false);
        //返回默认界面布局
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position) {
        NoteModel note = noteList.get(position);

        String content = note.getContent();
        long time = note.getTime();

        //根据数据渲染界面
        viewHolder.mTextViewContent.setText(content);
        viewHolder.mTextViewTitle.setText(dateFormat.format(time));
    }

    public void remove(int position) {
        NoteModel note = this.noteList.get(position);
        note.delete();
        this.noteList.remove(position);
    }

    @Override
    public int getItemCount() {
        return noteList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        @Bind(R.id.tv_title)
        public TextView mTextViewTitle;
        @Bind(R.id.tv_content)
        public TextView mTextViewContent;

        public ViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            int position = this.getAdapterPosition();
            NoteModel note = noteList.get(position);


            long id = note.getId();
            Intent intent = new Intent(mContext, EditActivity.class);
            intent.putExtra("id", id);
            ActivityOptions options =  ActivityOptions.makeSceneTransitionAnimation((Activity) mContext,
                    v, "content");
            mContext.startActivity(intent,
                    options.toBundle());
        }
    }

}

靠这一套AdapterRecyclerView就能一项一项渲染出咱们要的列表了。优化

关于数据

渲染界面少不了数据,咱们建立数据的入口在右下角,点"+"号就能够跳转到新建的页面
代码以下:ui

Intent intent = new Intent(this, EditActivity.class);
startActivity(intent);

两行便可搞定。

咱们跳转到新的界面

clipboard.png
在这里用户能够输入想要的内容,点右上角的保存便可保存。保存到内存很简单,咱们如何把数据持久化呢?
Android系统提供了SQLite来给咱们持久化数据。SQLite是一种轻量级的文件关系型数据库,能够知足咱们的需求,咱们使用SQLite存储用户输入的数据,而后保存到本地,就是这样。

关于Android中,SQLite的部分,能够看这个传送门:http://developer.android.com/training/basics/data-storage/databases.ht...

在这里,咱们为了方便直接使用ActiveAndroid的ORM方案(http://www.activeandroid.com/),能够
Model直接持久化到数据库,而后从数据库中读取数据。
咱们的模型以下:

@Column(name = "content")
private String content;

@Column(name = "time")
private long time;

public String getContent() {
    return content;
}

public void setContent(String content) {
    this.content = content;
}

public long getTime() {
    return time;
}

public void setTime(long time) {
    this.time = time;
}

public static List<NoteModel> queryNoteList() {
    return new Select().from(NoteModel.class).execute();
}

public static NoteModel queryById(long id) {
    return new Select().from(NoteModel.class)
                       .where("Id = ?", id).executeSingle();
}

咱们记录用户存入的内容,存入的事件,而后定义两个方法——列出全部存着的列表和根据id查询其中一个对象,咱们使用这两个方法就能获取到列表和详情两个数据。

列表数据提供给首页,详情数据提供给编辑页面。这样就知足了一个记事本App的基础需求——增长与修改。

列表页:
clipboard.png
详情页:

clipboard.png

若是对于写App入门还有什么问题,欢迎留言以及在Github上follow我

本文提到的项目源码地址:https://github.com/geminiwen/tudounotepad
欢迎留言Github或者@geminiwen

相关文章
相关标签/搜索