学了一段时间的Android,准备写一个简单的记事本练练手,本程序使用了litepal+recyclerview+一点Material Design中的界面设计,但由于本人审美水平原因,可能设计得不是很好看。
先上效果图:
添加依赖:
implementation 'com.android.support:design:29.1.1'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'org.litepal.android:java:3.0.0'
建立数据库
用litepal建立数据库,具体步骤我就不多说了,可以参考我上一条博客,这里就直接上代码
litepal.xml
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="TicklerDB"></dbname>
<version value="1"></version>
<list>
<mapping class="com.example.tickler.db.Tickler"></mapping>
</list>
</litepal>
Tickler.java这里在com.example.tickler目录下新建一个db文件夹
package com.example.tickler.db;
import org.litepal.crud.LitePalSupport;
public class Tickler extends LitePalSupport {
private int id;
private String content;
private String time;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
主页面代码及布局
先看主页面得布局activity_main.xml
这里用了加强版的帧布局:CoordinatorLayout,它可以解决在底部弹出消息时覆盖住了悬浮按钮的问题,然后就是Toolbar代替系统自带标题栏,还有下面的recyclerview和悬浮按钮的设置,由于是加强的帧布局,所有的控件都会在左上角,会造成recyclerview遮住toolbar的问题,这里用AppBarLayout让recyclerview下移一个toolbar的高度。
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add_tickler"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="20dp"
android:src="@drawable/add"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
MainActivity.java
package com.example.tickler;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.example.tickler.db.Tickler;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.litepal.LitePal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
private List<Map<String,String>> contentList=new ArrayList<Map<String, String>>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar=(Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton addContent=(FloatingActionButton) findViewById(R.id.add_tickler);
addContent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(MainActivity.this,AddContentActivity.class);
startActivity(intent);
}
});
}
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.main_toolbar,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
Toast.makeText(MainActivity.this,"敬请期待!",Toast.LENGTH_SHORT).show();
return true;
}
@Override
protected void onStart() {//每次活动有不可见变可见时调用
super.onStart();
contentList.clear();//清空list子项数据,实现刷新list
initContent();//初始化
RecyclerView recyclerView=(RecyclerView) findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager=new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
ContentAdapter adapter=new ContentAdapter(contentList);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
public void initContent(){
List<Tickler> ticklers= LitePal.order("id desc").find(Tickler.class);
for(Tickler tickler:ticklers){
String content=tickler.getContent();
String time=tickler.getTime();
Map<String,String> map=new HashMap<String, String>();
map.put("content",content);
map.put("time",time);
contentList.add(map);
}
}
}
main_toolbar.xml在res目录下新建一个文件夹menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/many_choose"
android:title="多选"
app:showAsAction="never"/>
<item
android:id="@+id/recently_deleted"
android:title="最近删除"
app:showAsAction="never"/>
</menu>
recyclerview的子项布局content_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="8dp"
app:cardCornerRadius="15dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/show_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_margin="5dp"
android:maxLines="1"/>
<TextView
android:id="@+id/show_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_margin="5dp"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
recyclerview的适配器ContentAdapter.java
package com.example.tickler;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import java.util.Map;
public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ViewHolder> {
private List<Map<String,String>> mContentList;
static class ViewHolder extends RecyclerView.ViewHolder{
View ticklerView;
TextView contentText;
TextView showTime;
public ViewHolder(View view){
super(view);
ticklerView=view;
contentText=(TextView) view.findViewById(R.id.show_content);
showTime=(TextView) view.findViewById(R.id.show_time);
}
}
public ContentAdapter(List<Map<String,String>> contentList){
mContentList=contentList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.content_item,parent,false);
//设置子项点击事件,并传递数据到添加页
final ViewHolder holder=new ViewHolder(view);
holder.ticklerView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position=holder.getAdapterPosition();
String content=mContentList.get(position).get("content");
String time=mContentList.get(position).get("time");
Intent intent=new Intent(parent.getContext(),AddContentActivity.class);
intent.putExtra(AddContentActivity.CONTENT,content);
intent.putExtra(AddContentActivity.TIME,time);
parent.getContext().startActivity(intent);
}
});
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.contentText.setText(mContentList.get(position).get("content"));
holder.showTime.setText(mContentList.get(position).get("time"));
}
@Override
public int getItemCount() {
return mContentList.size();
}
}
添加数据页面代码及布局
activity_add_content.xml
<?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"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar_1"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/time_show"
android:layout_weight="3"
android:layout_gravity="center_vertical"
android:textSize="20sp"
android:gravity="center"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/add_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:hint="请输入内容"/>
</LinearLayout>
</LinearLayout>
AddContentActivity.java
package com.example.tickler;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.example.tickler.db.Tickler;
import org.litepal.LitePal;
import java.text.SimpleDateFormat;
import java.util.Date;
public class AddContentActivity extends AppCompatActivity{
public static final String CONTENT="content";
public static final String TIME="time";
private String time;
private EditText content;
private TextView showTime;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_content);
content=(EditText) findViewById(R.id.add_content);
showTime=(TextView) findViewById(R.id.time_show);
Toolbar toolbar=(Toolbar) findViewById(R.id.toolbar_1);
setSupportActionBar(toolbar);
ActionBar actionBar=getSupportActionBar();
if(actionBar!=null){//显示系统返回按钮
actionBar.setDisplayHomeAsUpEnabled(true);
}
//取得内容和时间
Intent intent=getIntent();
time=intent.getStringExtra(TIME);
String showContent=intent.getStringExtra(CONTENT);
showTime.setText(time);
content.setText(showContent);
if(showContent!=null) {
content.setSelection(showContent.length());//将光标移动到文本最后
}
}
//配置菜单项设置点击事件
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.toolbar,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.save_content:
//判断当前操作是新增还是修改
if(time!=null){
String inputText=content.getText().toString();
Tickler tickler=new Tickler();
tickler.setContent(inputText);
tickler.updateAll("time=?",time);
finish();
break;
}else {
//取得新增记录时的系统时间
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date date=new Date(System.currentTimeMillis());
String inputText=content.getText().toString();
Tickler tickler=new Tickler();
tickler.setContent(inputText);
tickler.setTime(simpleDateFormat.format(date));
tickler.save();
Toast.makeText(this,"保存成功",Toast.LENGTH_SHORT).show();
finish();//操作完成结束当前活动
break;}
case R.id.delete:
//删除操作
String deleteContent=content.getText().toString();
LitePal.deleteAll(Tickler.class,"content=?",deleteContent);
finish();
break;
case android.R.id.home://一定添加android还有下面这行代码,我当时为这搞了半天
onBackPressed();
return true;
default:
}
return true;
}
}
菜单布局toolbar.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/delete"
app:showAsAction="ifRoom"
android:title="删除"
android:icon="@drawable/delete"/>
<item
android:id="@+id/save_content"
app:showAsAction="ifRoom"
android:title="保存"
android:icon="@drawable/save"/>
</menu>
主要的代码就是这些,附上源码:
链接:https://pan.baidu.com/s/1XszlojQGSLsn2pPM_XaoJA
提取码:g3zw