便签应用
便签应用实现的功能
1、便签应用的增删改查
2、修改便签应用的皮肤,和主页上的便签颜色同步
3、对便签应用的时间显示做一个特定显示:当天显示–>今天 hh:mm ,昨天显示 --> 昨天 hh:mm,本周内显示–> 周几 hh:mm,否则显示 yyyy/MM/dd
4、在便签的编辑页面,可以设置便签的提醒时间,第一次选择日期,第二次选择时间
5、长按主页对便签进行整体操作
6、可以为便签设置顶置设置,可以单个设置,也可以批量设置
7、当便签全部顶置的时候,长按编辑的顶置 按钮变成了取消顶置 按钮
7、当选择未顶置的标签,会提示是否顶置标签,反之如此
便签应用的整体思路和代码
1、首先对便签应用的主页布局进行构思,
具体的数据显示使用RecyclerView 进行数据展示,主页的布局显示一个新建按钮,并且其中隐藏着长按之后的布局(取消、全选、顶置、删除);并在布局中的visibility 设为 gone
activity_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
android:orientation="vertical">
<Toolbar
android:id="@+id/id_note_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/toolbar"
android:visibility="gone">
<Button
android:id="@+id/header_cancel"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_gravity="left"
android:gravity="center"
android:background="@drawable/button_style"
android:backgroundTint="@color/toolbar_button"
android:text="@string/press_cancel"
android:textSize="15sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="@color/white"
android:text="@string/press_edit"
android:textSize="20sp"/>
<Button
android:id="@+id/header_selectAll"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_gravity="right"
android:background="@drawable/button_style"
android:backgroundTint="@color/toolbar_button"
android:textColor="@color/white"
android:layout_marginRight="20dp"
android:text="@string/press_selectAll"
android:textSize="15sp"/>
</Toolbar>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</androidx.recyclerview.widget.RecyclerView>
<LinearLayout
android:id="@+id/id_note_add"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_weight="1"
android:background="#302424"
android:orientation="vertical"
android:visibility="visible">
<ImageView
android:id="@+id/add_pic"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@mipmap/ic_note_add"
android:layout_gravity="center"
android:layout_weight="1"/>
<TextView
android:id="@+id/add_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="15sp"
android:text="@string/main_add"
android:gravity="center"
android:textColor="@color/white"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:id="@+id/id_note_bottom"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_weight="1"
android:orientation="horizontal"
android:visibility="gone"
android:background="@color/purple_200">
<LinearLayout
android:id="@+id/header_top"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:background="@color/toolbar"
android:orientation="vertical">
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:src="@mipmap/ic_note_edit_top"/>
<TextView
android:id="@+id/tv_header_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="@color/white"
android:textSize="15sp"
android:paddingTop="5dp"
android:text="@string/home_top"/>
</LinearLayout>
<TextView
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#4f4545"/>
<LinearLayout
android:id="@+id/header_delete"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@color/toolbar"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:src="@mipmap/ic_note_edit_delete"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="@color/white"
android:textSize="15sp"
android:paddingTop="5dp"
android:text="@string/delete"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
初始主页布局:
隐藏的主页布局(长按之后显示):
2、对每个item的具体布局,使用RecyclerView布局显示
note_item.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="wrap_content"
android:orientation="horizontal"
android:padding="5dp">
<LinearLayout
android:id="@+id/lr_list_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/menu_theme4">
<ImageView
android:id="@+id/iv_topTab"
android:visibility="invisible"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@mipmap/ic_header_top"/>
<LinearLayout
android:id="@+id/recycler_background"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_weight="1"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_time"
android:layout_gravity="center"
android:layout_marginTop="5dp"
android:maxLines="2"
android:text="我也不想这样"
android:textColor="@color/black"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="100dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:paddingLeft="5dp"
android:text="2021/5/30 02:30"
android:textColor="@color/black"
android:textSize="16sp"
android:layout_weight="1"
android:gravity="right"/>
<LinearLayout
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_remind"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginRight="10dp"
android:src="@mipmap/ic_note_clock"
android:visibility="visible" />
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:buttonTint="#ffffff"
android:checked="false"
android:gravity="center_vertical"
android:scaleX="1.5"
android:scaleY="1.5"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
显示效果:checkbox进行隐藏(gone),当长按的时候,出现checkbox
3、recyclerView的适配器代码
RecyclerAdapter.java
package com.tinno.adapter;
import static android.view.View.VISIBLE;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.RecyclerView;
import com.tinno.bean.Note;
import com.tinno.db.NoteDbHelper;
import com.tinno.sticky_note.EditNoteActivity;
import com.tinno.sticky_note.MainActivity;
import com.tinno.sticky_note.R;
import com.tinno.utils.FormatTime;
import java.io.Serializable;
import java.util.List;
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder> {
private static final String TAG = "RecyclerAdapter";
private List<Note> mBeanList;
private Context mContext;
private boolean showIcon = false;
private int flag = 0;
public boolean isCheck;
private LinearLayout mNoteAdd,mNoteBottom;
private Toolbar noteToolbar;
public RecyclerAdapter(Context context, List<Note> mBeanList) {
this.mContext = context;
this.mBeanList = mBeanList;
}
@NonNull
@Override
public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.note_item, parent, false);
return new RecyclerViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
Note note = mBeanList.get(position);
holder.mTvCreateTime.setText(FormatTime.FormatTimeForDb(note.getCreatedTime()));
holder.mTvContent.setText(note.getContent());
holder.lrContainer.setBackgroundColor(note.getColor());
holder.lrContainer.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
flag++;
Log.d(TAG, "showIcon " + showIcon);
if (flag % 2 == 0 ){
showIcon = false;
}else {
showIcon = true;
}
showOrHide(showIcon);
notifyItemRangeChanged(0,mBeanList.size());
return true;
}
});
holder.mCheckBox.setVisibility(showIcon ? VISIBLE : View.GONE);
holder.lrContainer.setOnClickListener(view -> {
Intent intent = new Intent(mContext, EditNoteActivity.class);
intent.putExtra("note",note);
Log.d(TAG, "adapter向activity中传的值为: " + note.getId());
mContext.startActivity(intent);
});
NoteDbHelper noteDbHelper = new NoteDbHelper(mContext);
List<Note> noteList = noteDbHelper.queryAllFromDb();
if (TextUtils.isEmpty(noteList.get(position).getRemind())){
holder.mTvRemind.setVisibility(View.GONE);
}else {
holder.mTvRemind.setVisibility(VISIBLE);
holder.mTvRemind.setOnClickListener(view -> {
showDialog(noteList.get(position).getRemind());
});
}
if (noteList.get(position).getIsTop() == 1){
holder.mIvTopTab.setVisibility(VISIBLE);
}else if (noteList.get(position).getIsTop() == 0){
holder.mIvTopTab.setVisibility(View.INVISIBLE);
}
}
public void showDialog(String str){
AlertDialog dialog = new AlertDialog.Builder(mContext)
.setTitle("事件提醒")
.setMessage(str + "\n" + str)
.create();
dialog.show();
}
public void showOrHide(boolean isShow){
mNoteAdd = ((MainActivity) mContext).findViewById(R.id.id_note_add);
mNoteBottom = ((MainActivity) mContext).findViewById(R.id.id_note_bottom);
noteToolbar = ((MainActivity) mContext).findViewById(R.id.id_note_toolbar);
if (isShow){
mNoteAdd.setVisibility(View.GONE);
mNoteBottom.setVisibility(VISIBLE);
noteToolbar.setVisibility(VISIBLE);
}else {
mNoteAdd.setVisibility(VISIBLE);
mNoteBottom.setVisibility(View.GONE);
noteToolbar.setVisibility(View.GONE);
}
}
@Override
public int getItemCount() {
return mBeanList == null ? 0 : mBeanList.size();
}
@Override
public long getItemId(int position) {
return position;
}
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
private TextView mTvCreateTime;
private TextView mTvContent;
private ImageView mTvRemind,mIvTopTab;
private ViewGroup lrContainer;
private LinearLayout recycler_background;
private CheckBox mCheckBox;
public RecyclerViewHolder(@NonNull View itemView) {
super(itemView);
mTvCreateTime = itemView.findViewById(R.id.tv_time);
mTvContent = itemView.findViewById(R.id.tv_content);
mTvRemind = itemView.findViewById(R.id.iv_remind);
lrContainer = itemView.findViewById(R.id.lr_list_container);
mCheckBox = itemView.findViewById(R.id.checkbox);
recycler_background = itemView.findViewById(R.id.recycler_background);
mIvTopTab = itemView.findViewById(R.id.iv_topTab);
mCheckBox.setOnClickListener(view -> {
if (mCheckBox.isChecked()){
mOnItemClickListener.onRecyclerItemClick(getAdapterPosition());
}
});
}
}
private OnRecyclerItemClickListener mOnItemClickListener;
public void setRecyclerItemClickListener(OnRecyclerItemClickListener listener){
mOnItemClickListener = listener;
}
public interface OnRecyclerItemClickListener{
void onRecyclerItemClick(int position);
}
}
4、主启动器的代码,
并为主页面的一些控件设置点击事件
MainActivity.java
package com.tinno.sticky_note;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.tinno.adapter.RecyclerAdapter;
import com.tinno.bean.Note;
import com.tinno.db.NoteDbHelper;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private Context mContext;
private List<Note> data;
private RecyclerView mRecyclerView;
private RecyclerAdapter mRecyclerAdapter;
private List<String> list;
private NoteDbHelper mNoteDbHelper = new NoteDbHelper(this);
private LinearLayout mNoteAdd;
private Button headerCancel,headerSelectAll;
private LinearLayout headerTop,headerDelete;
private TextView tvHeaderTop;
private ImageView addpic;
private Intent intent;
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
mNoteAdd = findViewById(R.id.id_note_add);
mNoteAdd.setOnClickListener(this);
initView();
}
@Override
protected void onResume() {
super.onResume();
mRecyclerView = (RecyclerView) findViewById(R.id.recycler);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext);
mRecyclerView.setLayoutManager(linearLayoutManager);
mNoteDbHelper = new NoteDbHelper(mContext);
data = new ArrayList<>();
Log.d(TAG, "init: ....." );
data = mNoteDbHelper.queryAllFromDb();
mRecyclerAdapter = new RecyclerAdapter(mContext,data);
mRecyclerView.setAdapter(mRecyclerAdapter);
ChangeTopButtonContent();
show();
}
public void show(){
list = new ArrayList<>();
mRecyclerAdapter.setRecyclerItemClickListener(position -> {
list.add(data.get(position).getId());
Log.d(TAG, "show: " + list);
if (data.get(position).getIsTop() == 1){
Toast.makeText(mContext, "是否取消顶置", Toast.LENGTH_SHORT).show();
tvHeaderTop.setText("取消顶置");
}else {
Toast.makeText(mContext, "是否顶置", Toast.LENGTH_SHORT).show();
tvHeaderTop.setText("顶置");
}
});
}
public void ChangeTopButtonContent(){
List<Integer> list = new ArrayList<>();
for (Note datum : data) {
list.add(datum.getIsTop());
}
if (list != null){
int first = list.get(0);
for (Integer integer : list) {
if(integer.equals(first)){
tvHeaderTop.setText("取消顶置");
}else {
tvHeaderTop.setText("顶置");
}
}
}
}
public void initView(){
headerCancel = (Button) findViewById(R.id.header_cancel);
headerSelectAll = (Button) findViewById(R.id.header_selectAll);
headerTop = (LinearLayout) findViewById(R.id.header_top);
headerDelete = (LinearLayout) findViewById(R.id.header_delete);
tvHeaderTop = (TextView) findViewById(R.id.tv_header_top);
addpic = (ImageView) findViewById(R.id.add_pic);
headerCancel.setOnClickListener(this);
headerSelectAll.setOnClickListener(this);
headerTop.setOnClickListener(this);
headerDelete.setOnClickListener(this);
addpic.setOnClickListener(this);
}
public void showHome(){
RecyclerAdapter adapter = new RecyclerAdapter(mContext,data);
adapter.showOrHide(false);
onResume();
}
public void setThingTop(){
for (Note datum : data) {
Log.d(TAG, "onClick: " + datum);
for (String noteId : list){
if (datum.getId().equals(noteId)){
Log.d(TAG, "onClick: -------------------------------------------");
Log.d(TAG, "获取的事件: " + datum.getContent() + "=>" + datum.getId());
Note n = new Note();
n.setId(datum.getId());
n.setContent(datum.getContent());
n.setRemind(datum.getRemind());
n.setColor(datum.getColor());
n.setCreatedTime(datum.getCreatedTime());
if (tvHeaderTop.getText().toString().equals("顶置")){
n.setIsTop(1);
}else if (tvHeaderTop.getText().toString().equals("取消顶置")){
n.setIsTop(0);
}
mNoteDbHelper.updateData(n);
Log.d(TAG, "获取新的Note对象:" + n);
Log.d(TAG, "onClick: ---------------------------------------------" );
}
}
}
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.add_pic:
intent = new Intent(this, AddNoteActivity.class);
startActivity(intent);
break;
case R.id.header_cancel:
showHome();
break;
case R.id.header_selectAll:
break;
case R.id.header_top:
setThingTop();
showHome();
break;
case R.id.header_delete:
for (String s : list) {
mNoteDbHelper.deleteFromDbById(s);
}
showHome();
break;
}
}
}
5、创建数据库
为了存储数据的方法,为便签应用创建noteSql 数据库,并创建 note 数据表,并在该类中初始化数据库操作的CURD的方法。
NoteDbHelper.java
package com.tinno.db;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.tinno.bean.Note;
import java.util.ArrayList;
import java.util.List;
public class NoteDbHelper extends SQLiteOpenHelper {
private static final String TAG = "NoteDbHelper";
private Context context;
private static final String DB_NAME = "noteSql.db";
private static final String NOTE_TABLE_NAME = "note";
private static final int DATABASE_VERSION =1;
private static final String CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS " + NOTE_TABLE_NAME + " (id INTEGER PRIMARY KEY AUTOINCREMENT, content TEXT, create_time TEXT, remind TEXT, color TEXT,isTop TEXT)";
public NoteDbHelper(Context context){
super(context,DB_NAME,null,DATABASE_VERSION);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_SQL);
Toast.makeText(context, "创建数据库成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
public List<Note> queryAllFromDb(){
SQLiteDatabase db = getWritableDatabase();
List<Note> noteList = new ArrayList<>();
Cursor cursor = db.query(NOTE_TABLE_NAME, null, null, null, null, null, "isTop DESC");
if (cursor != null){
while (cursor.moveToNext()){
String id = cursor.getString(cursor.getColumnIndexOrThrow("id"));
String content = cursor.getString(cursor.getColumnIndexOrThrow("content"));
String createTime = cursor.getString(cursor.getColumnIndexOrThrow("create_time"));
String remind = cursor.getString(cursor.getColumnIndexOrThrow("remind"));
int color = cursor.getInt(cursor.getColumnIndexOrThrow("color"));
int isTop = cursor.getInt(cursor.getColumnIndexOrThrow("isTop"));
Note note = new Note();
note.setId(id);
note.setContent(content);
note.setCreatedTime(createTime);
note.setRemind(remind);
note.setColor(color);
note.setIsTop(isTop);
noteList.add(note);
}
cursor.close();
}
return noteList;
}
public long insertData(Note note){
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("content",note.getContent());
values.put("create_time",note.getCreatedTime());
values.put("remind",note.getRemind());
values.put("color",note.getColor());
values.put("isTop",note.getIsTop());
return db.insert(NOTE_TABLE_NAME,null,values);
}
public int deleteFromDbById(String id) {
SQLiteDatabase db = getWritableDatabase();
return db.delete(NOTE_TABLE_NAME, "id like ?", new String[]{id});
}
public int updateData(Note note) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("content", note.getContent());
values.put("create_time", note.getCreatedTime());
values.put("remind",note.getRemind());
values.put("color",note.getColor());
values.put("isTop",note.getIsTop());
Log.d(TAG, "updateData: " + values);
return db.update(NOTE_TABLE_NAME, values, "id like ?", new String[]{note.getId()});
}
public List<Note> queryFromDbByContent(String content) {
if (TextUtils.isEmpty(content)) {
return queryAllFromDb();
}
SQLiteDatabase db = getWritableDatabase();
List<Note> noteList = new ArrayList<>();
Cursor cursor = db.query(NOTE_TABLE_NAME, null, "content like ?", new String[]{"%"+content+"%"}, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndexOrThrow("id"));
String content2 = cursor.getString(cursor.getColumnIndexOrThrow("content"));
String createTime = cursor.getString(cursor.getColumnIndexOrThrow("create_time"));
String remind = cursor.getString(cursor.getColumnIndexOrThrow("remind"));
int color = cursor.getInt(cursor.getColumnIndexOrThrow("color"));
int isTop = cursor.getInt(cursor.getColumnIndexOrThrow("isTop"));
Note note = new Note();
note.setId(id);
note.setContent(content2);
note.setCreatedTime(createTime);
note.setRemind(remind);
note.setColor(color);
note.setIsTop(isTop);
noteList.add(note);
}
cursor.close();
}
return noteList;
}
}
6、时间初始化
初始化便签创建的时候(存入数据库数据)以及具体显示在页面上的时间
FormatTime.java
package com.tinno.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
public class FormatTime {
public static String getCurrentTimeFormat(){
long currentTime = System.currentTimeMillis();
String timeNow = new SimpleDateFormat("yyyy/MM/dd HH:mm").format(currentTime);
return timeNow;
}
public static String FormatTimeForDb(String time){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm");
Date date2;
date2 = new Date(System.currentTimeMillis());
int year1 = Integer.parseInt(time.substring(0,4));
int month1 = Integer.parseInt(time.substring(5,7));
int day1 = Integer.parseInt(time.substring(8,10));
int h1 = Integer.parseInt(time.substring(11,13));
int m1 = Integer.parseInt(time.substring(14,16));
String str2 = simpleDateFormat.format(date2);
int year2 = Integer.parseInt(str2.substring(0, 4));
int month2 = Integer.parseInt(str2.substring(5, 7));
int day2 = Integer.parseInt(str2.substring(8, 10));
int h2 = Integer.parseInt(str2.substring(11, 13));
int m2 = Integer.parseInt(str2.substring(14, 16));
if (year2 > year1) {
return year1 + "/" + time.substring(5, 7) + "/" + time.substring(8, 10);
} else if (month2 > month1) {
return year1 + "/" + time.substring(5, 7) + "/" + time.substring(8, 10);
} else if (day2 > day1) {
if (day2 - day1 == 1){
return "昨天 " + time.substring(11,13) + ":" + time.substring(14,16);
}else if (day2 - day1 < 7){
return getWeek(time) + " " + time.substring(11,13) + ":" + time.substring(14,16);
}else {
return year1 + "/" + time.substring(5, 7) + "/" + time.substring(8, 10);
}
} else {
return "今天 " + time.substring(11, 13) + ":" + time.substring(14, 16);
}
}
private static int getDayofWeek(String dateTime) {
Calendar cal = Calendar.getInstance();
if (dateTime.equals("")) {
cal.setTime(new Date(System.currentTimeMillis()));
} else {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd", Locale.getDefault());
Date date;
try {
date = sdf.parse(dateTime);
} catch (ParseException e) {
date = null;
e.printStackTrace();
}
if (date != null) {
cal.setTime(new Date(date.getTime()));
}
}
return cal.get(Calendar.DAY_OF_WEEK);
}
public static String getWeek(String time){
int dayofWeek = getDayofWeek(time);
if (1 == dayofWeek){
return "周日";
}else if (2 == dayofWeek){
return "周一";
}else if (3 ==dayofWeek){
return "周二";
}else if (4 == dayofWeek){
return "周三";
}else if (5==dayofWeek){
return "周四";
}else if (6 == dayofWeek){
return "周五";
}else{
return "周六";
}
}
}
7、便签皮肤展示和修改
使用popupWindow 控件对便签皮肤的效果进行展示,并为每个皮肤设置点击事件,监控点击并更改主题颜色
popupWindow 的布局popup_theme.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:layout_width="320dp"
android:layout_height="80dp"
android:orientation="horizontal"
android:background="@color/menu_background"
android:layout_gravity="end"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp">
<FrameLayout
android:id="@+id/theme1"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/menu_theme1"
android:layout_gravity="center"
android:layout_margin="10dp"/>
<FrameLayout
android:id="@+id/theme2"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/menu_theme2"
android:layout_gravity="center"
android:layout_margin="10dp"/>
<FrameLayout
android:id="@+id/theme3"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/menu_theme3"
android:layout_gravity="center"
android:layout_margin="10dp"/>
<FrameLayout
android:id="@+id/theme4"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/menu_theme4"
android:layout_gravity="center"
android:layout_margin="10dp"/>
</LinearLayout>
</LinearLayout>
效果:
代码实现:
public void showPopupWindow(View view){
View popupView = getLayoutInflater().inflate(R.layout.popup_theme,null);
FrameLayout btn1,btn2,btn3,btn4;
btn1 = popupView.findViewById(R.id.theme1);
btn2 = popupView.findViewById(R.id.theme2);
btn3 = popupView.findViewById(R.id.theme3);
btn4 = popupView.findViewById(R.id.theme4);
PopupWindow popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT,true);
popupWindow.showAsDropDown(edit_themes);
btn1.setOnClickListener(view1 -> {
content_container.setBackgroundColor(Color.parseColor("#BFC8FD"));
edit_themes.setBackgroundColor(Color.parseColor("#BFC8FD"));
Log.d(TAG, "showPopupWindow: 颜色");
popupWindow.dismiss();
});
btn2.setOnClickListener(view1 -> {
content_container.setBackgroundColor(Color.parseColor("#A5EEE5"));
edit_themes.setBackgroundColor(Color.parseColor("#A5EEE5"));
popupWindow.dismiss();
});
btn3.setOnClickListener(view1 -> {
content_container.setBackgroundColor(Color.parseColor("#FCBEBE"));
edit_themes.setBackgroundColor(Color.parseColor("#FCBEBE"));
popupWindow.dismiss();
});
btn4.setOnClickListener(view1 -> {
content_container.setBackgroundColor(Color.parseColor("#FFF195"));
edit_themes.setBackgroundColor(Color.parseColor("#FFF195"));
popupWindow.dismiss();
});
}
8、时间和日期选择器
在编辑和新增页面中,点击闹钟按钮,添加提醒时间,弹出3个dialog,第一个是便签提醒文字,点击确认弹出日期选择器,选择日期后,上面的日期框出现选中的日期,在点击确认按钮,弹出时间选择器,点击确认市,上面的textView出现选择的日期和时间。
先为日期和时间选择器完成一个布局,在基于这个布局进行一个dialog的弹窗实现
dialog_date_select.xml
<?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:layout_gravity="center_horizontal"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/set_alarm_title"
android:textStyle="bold"
android:textSize="20sp"
android:typeface="serif"
android:layout_marginTop="5dp"
android:textColor="@color/black"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:gravity="center">
<TextView
android:id="@+id/dds_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="时间(10:55)"
android:textSize="16sp"
android:layout_weight="1" />
<TextView
android:id="@+id/dds_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="日期(06/27)"
android:layout_weight="1"
android:textSize="16sp" />
</LinearLayout>
<DatePicker
android:id="@+id/date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:spinnersShown="false" />
<TimePicker
android:id="@+id/time_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" />
</LinearLayout>
效果:
实现代码
public void showDialog(){
final EditText message = new EditText(this);
message.setPadding(10,10,10,10);
message.setTextColor(Color.BLACK);
message.setBackgroundColor(Color.WHITE);
TextView title = new TextView(this);
title.setText("便签提醒");
title.setPadding(10,10,10,10);
title.setGravity(Gravity.CENTER);
title.setTextColor(Color.BLACK);
title.setTextSize(26);
title.setBackgroundColor(Color.parseColor("#F2F2F2"));
AlertDialog dialog = new AlertDialog.Builder(this)
.setView(message)
.setCustomTitle(title)
.setNeutralButton("进入便签", null)
.setPositiveButton("确认",null)
.create();
dialog.show();
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialog.dismiss();
}
});
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "获取输入框的内容:" + message.getText().toString(), Toast.LENGTH_SHORT).show();
showDate();
}
});
}
public void initShowDateView(){
v = View.inflate(context,R.layout.dialog_date_select,null);
datePicker = (DatePicker) v.findViewById(R.id.date_picker);
timePicker = (TimePicker) v.findViewById(R.id.time_picker);
ddsDate = (TextView) v.findViewById(R.id.dds_date);
ddsTime = (TextView) v.findViewById(R.id.dds_time);
}
public void showDate(){
initShowDateView();
((ViewGroup)v).removeView(timePicker);
AlertDialog alertDialog = new AlertDialog.Builder(context)
.setView(v)
.setNeutralButton(getString(R.string.cancel),null)
.setPositiveButton(getString(R.string.sure),null)
.create();
alertDialog.show();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DAY_OF_MONTH);
datePicker.init(year, month, day, (datePicker1, i, i1, i2) -> {
this.year = i;
this.month = i1 + 1;
this.day = i2;
ddsDate.setText(year+"/"+month+"/"+day);
});
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(view -> {
alertDialog.dismiss();
});
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(view -> {
showTime();
});
}
public void showTime(){
initShowDateView();
((ViewGroup)v).removeView(datePicker);
((ViewGroup)v).removeView(timePicker);
((ViewGroup)v).addView(timePicker);
AlertDialog dialog = new AlertDialog.Builder(context)
.setView(v)
.setNeutralButton(getString(R.string.cancel),null)
.setPositiveButton(getString(R.string.sure),null)
.create();
dialog.show();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
timePicker.setIs24HourView(true);
timePicker.setCurrentHour(calendar.get(Calendar.HOUR_OF_DAY));
timePicker.setCurrentMinute(Calendar.MINUTE);
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(view -> {
dialog.dismiss();
});
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(view -> {
String CurrentHour = timePicker.getCurrentHour().toString();
String CurrentMinute = timePicker.getCurrentMinute().toString();
if (timePicker.getCurrentHour() >= 0 && timePicker.getCurrentHour() <= 9) {
CurrentHour = "0" + timePicker.getCurrentHour() ;
}
if (timePicker.getCurrentMinute() >= 0 && timePicker.getCurrentMinute() <= 9) {
CurrentMinute = "0" + timePicker.getCurrentMinute();
}
StringBuffer sb = new StringBuffer();
sb.append(String.format("%d/%02d/%02d",
datePicker.getYear(),
datePicker.getMonth() + 1,
datePicker.getDayOfMonth()));
sb.append(" ");
sb.append(CurrentHour)
.append(":")
.append(CurrentMinute);
String ttime = sb.toString();
String[] s = ttime.split(" ");
ddsDate.setText(s[0]);
ddsTime.setText(s[1]);
Note n = new Note();
n.setId(note.getId());
n.setCreatedTime(note.getCreatedTime());
n.setColor(note.getColor());
n.setContent(note.getContent());
n.setIsTop(note.getIsTop());
n.setRemind(ttime);
Log.d(TAG, "获取的值 : " + n);
mNoteDbHelper = new NoteDbHelper(this);
mNoteDbHelper.updateData(n);
finish();
});
}
9、长按编辑功能
在主页中,长按某一个item,出现四个编辑按钮和多选按钮,可以对主页便签进行顶置、删除等功能
删除功能
实现代码:
-
首先对长按后的一个控件显示和隐藏功能 @Override
public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
Note note = mBeanList.get(position);
holder.mTvCreateTime.setText(FormatTime.FormatTimeForDb(note.getCreatedTime()));
holder.mTvContent.setText(note.getContent());
holder.lrContainer.setBackgroundColor(note.getColor());
holder.lrContainer.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
flag++;
Log.d(TAG, "showIcon " + showIcon);
if (flag % 2 == 0 ){
showIcon = false;
}else {
showIcon = true;
}
showOrHide(showIcon);
notifyItemRangeChanged(0,mBeanList.size());
return true;
}
});
holder.mCheckBox.setVisibility(showIcon ? VISIBLE : View.GONE);
......
......
......
}
public void showOrHide(boolean isShow){
mNoteAdd = ((MainActivity) mContext).findViewById(R.id.id_note_add);
mNoteBottom = ((MainActivity) mContext).findViewById(R.id.id_note_bottom);
noteToolbar = ((MainActivity) mContext).findViewById(R.id.id_note_toolbar);
if (isShow){
mNoteAdd.setVisibility(View.GONE);
mNoteBottom.setVisibility(VISIBLE);
noteToolbar.setVisibility(VISIBLE);
}else {
mNoteAdd.setVisibility(VISIBLE);
mNoteBottom.setVisibility(View.GONE);
noteToolbar.setVisibility(View.GONE);
}
}
-
在RecyclerAdapter 中自定义一个接口,用来接收多选框的点击事件。 public class RecyclerViewHolder extends RecyclerView.ViewHolder {
private TextView mTvCreateTime;
private TextView mTvContent;
private ImageView mTvRemind,mIvTopTab;
private ViewGroup lrContainer;
private LinearLayout recycler_background;
private CheckBox mCheckBox;
public RecyclerViewHolder(@NonNull View itemView) {
super(itemView);
mTvCreateTime = itemView.findViewById(R.id.tv_time);
mTvContent = itemView.findViewById(R.id.tv_content);
mTvRemind = itemView.findViewById(R.id.iv_remind);
lrContainer = itemView.findViewById(R.id.lr_list_container);
mCheckBox = itemView.findViewById(R.id.checkbox);
recycler_background = itemView.findViewById(R.id.recycler_background);
mIvTopTab = itemView.findViewById(R.id.iv_topTab);
mCheckBox.setOnClickListener(view -> {
if (mCheckBox.isChecked()){
mOnItemClickListener.onRecyclerItemClick(getAdapterPosition());
}
});
}
}
private OnRecyclerItemClickListener mOnItemClickListener;
public void setRecyclerItemClickListener(OnRecyclerItemClickListener listener){
mOnItemClickListener = listener;
}
public interface OnRecyclerItemClickListener{
void onRecyclerItemClick(int position);
}
-
在MainActivity.java 中获取 RecyclerView中CheckBox的选择框内容
public void show(){
list = new ArrayList<>();
mRecyclerAdapter.setRecyclerItemClickListener(position -> {
list.add(data.get(position).getId());
Log.d(TAG, "show: " + list);
if (data.get(position).getIsTop() == 1){
Toast.makeText(mContext, "是否取消顶置", Toast.LENGTH_SHORT).show();
tvHeaderTop.setText("取消顶置");
}else {
Toast.makeText(mContext, "是否顶置", Toast.LENGTH_SHORT).show();
tvHeaderTop.setText("顶置");
}
});
-
返回主页的一个原始状态
public void showHome(){
RecyclerAdapter adapter = new RecyclerAdapter(mContext,data);
adapter.showOrHide(false);
onResume();
}
-
在点击按钮中,调用方法,获取点击的checkbox的数据id,进行一个数据删除
@Override
public void onClick(View view) {
switch (view.getId()){
....
....
case R.id.header_delete:
for (String s : list) {
mNoteDbHelper.deleteFromDbById(s);
}
showHome()
break;
}
}
顶置功能
实现代码
@Override
public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
Note note = mBeanList.get(position);
holder.mTvCreateTime.setText(FormatTime.FormatTimeForDb(note.getCreatedTime()));
holder.mTvContent.setText(note.getContent());
holder.lrContainer.setBackgroundColor(note.getColor());
......
......
......
if (noteList.get(position).getIsTop() == 1){
holder.mIvTopTab.setVisibility(VISIBLE);
}else if (noteList.get(position).getIsTop() == 0){
holder.mIvTopTab.setVisibility(View.INVISIBLE);
}
}
public void setThingTop(){
for (Note datum : data) {
Log.d(TAG, "onClick: " + datum);
for (String noteId : list){
if (datum.getId().equals(noteId)){
Log.d(TAG, "onClick: -------------------------------------------");
Log.d(TAG, "获取的事件: " + datum.getContent() + "=>" + datum.getId());
Note n = new Note();
n.setId(datum.getId());
n.setContent(datum.getContent());
n.setRemind(datum.getRemind());
n.setColor(datum.getColor());
n.setCreatedTime(datum.getCreatedTime());
if (tvHeaderTop.getText().toString().equals("顶置")){
n.setIsTop(1);
}else if (tvHeaderTop.getText().toString().equals("取消顶置")){
n.setIsTop(0);
}
mNoteDbHelper.updateData(n);
Log.d(TAG, "获取新的Note对象:" + n);
Log.d(TAG, "onClick: ---------------------------------------------" );
}
}
}
}
@Override
public void onClick(View view) {
switch (view.getId()){
....
....
case R.id.header_top:
setThingTop();
showHome();
break;
....
....
}
}
10、为主页中的便签设置了闹钟功能的便签显示一个小闹钟图标
-
在RecyclerAdapter @Override
public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
Note note = mBeanList.get(position);
holder.mTvCreateTime.setText(FormatTime.FormatTimeForDb(note.getCreatedTime()));
holder.mTvContent.setText(note.getContent());
holder.lrContainer.setBackgroundColor(note.getColor());
......
......
......
NoteDbHelper noteDbHelper = new NoteDbHelper(mContext);
List<Note> noteList = noteDbHelper.queryAllFromDb();
if (TextUtils.isEmpty(noteList.get(position).getRemind())){
holder.mTvRemind.setVisibility(View.GONE);
}else {
holder.mTvRemind.setVisibility(VISIBLE);
holder.mTvRemind.setOnClickListener(view -> {
showDialog(noteList.get(position).getRemind());
});
}
......
......
......
}
public void showDialog(String str){
AlertDialog dialog = new AlertDialog.Builder(mContext)
.setTitle("事件提醒")
.setMessage(str + "\n" + str)
.create();
dialog.show();
}
效果
整体的代码(Demo)
gitee地址: https://gitee.com/SmellWang/sticky_-note.git
|