软件介绍下载
该软件是本人学习安卓开发而创作的一款通知提醒、笔记创作的app,笔记可以选择背景图片,更改字体颜色等特色功能。
该软件下载地址https://senzhijing.github.io/xiaowangzi/app-release.apk
GitHub地址: xiaowangzi/app-release.apk at main · SenZhijing/xiaowangzi · GitHub
效果图
部分功能代码
ruturnBar,自定义组件由于子组件太少,所以直接在代码中添加子组件了
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import abc.szj.myapps.R;
public class ReturnBur extends Toolbar{
public ReturnBur(@NonNull Context context) {
super(context);
initView(context);
}
public ReturnBur(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView(context);
}
TextView title;
/**
* 获取自定的标题,用来设置标题;
* @return
*/
public TextView gettitle() {
return title;
}
private void initView(Context context){
ImageButton fanhui=new ImageButton(context);
fanhui.setBackgroundColor(Color.TRANSPARENT);
fanhui.setImageResource(R.drawable.back);
fanhui.setOnClickListener(v-> ((Activity) context).finish());
addView(fanhui);
title=new TextView(context);
title.setTextSize(20);
title.setText("title");
Toolbar.LayoutParams layoutParams=new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
addView(title,layoutParams);
setBackgroundColor(Color.rgb(187,203,218));
}
}
sqlOpenHelper sqlite工具类
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
public class SqlOphelper extends SQLiteOpenHelper {
public static final String DBName="userdata.db";
private SqlOphelper(Context context){
super(context,DBName,null,1);
}
private static SqlOphelper sqlOphelper=null;
/**
* 获取本类的实例对象
* @param context
* @return
*/
public static SqlOphelper getInstance(Context context){
if (sqlOphelper==null){
sqlOphelper=new SqlOphelper(context);
}
return sqlOphelper;
}
private SQLiteDatabase writeDb=null,readDb=null;
public SQLiteDatabase getWriteDb(){
if (writeDb==null||!writeDb.isOpen()){
writeDb=sqlOphelper.getWritableDatabase();
}
return writeDb;
}
public SQLiteDatabase getReadDb(){
if (readDb==null||!readDb.isOpen()){
readDb=sqlOphelper.getReadableDatabase();
}
return readDb;
}
public SqlOphelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
public static final String select="select *from yhtzjl order by id desc";
public static final String insert="insert into yhtzjl(tztitle,tzneiron,tzcjsj)values(?,?,?)";
public static final String update="update yhtzjl set tztitle=?,tzneiron=? where id=?";
public static final String updatebjjl="update yhbjjl set bjtitle=?,bjneiron=?,bjgxsj=?, bjbjt=?,bjnrys=?, nrztdx=? where id=?";
public static final String delete="delete from yhtzjl where id=?";
public static final String YHTZb="yhtzjl";
public static final String YHBJb="yhbjjl";
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table yhtzjl(id integer primary key autoincrement,tztitle text unique,tzneiron text not null,tzcjsj text)");
db.execSQL("create table yhbjjl(id integer primary key autoincrement,bjtitle text ,bjneiron text ,bjcjsj text,bjgxsj text,zyxdj integer not null,bjbjt text,bjnrys integer,nrztdx integer not null)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
/*switch (newVersion){
case 2: db.execSQL("alert table yhbjjl drop constraint unique ");
break;
default:
throw new IllegalStateException("Unexpected value: " + newVersion);
}*/
}
}
通知编辑页面
package abc.szj.myapps;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.app.AlertDialog;
import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import abc.szj.myapps.others.TzhiInfo;
import abc.szj.myapps.others.ReturnBur;
import abc.szj.myapps.others.SqlOphelper;
import abc.szj.myapps.others.UtilToast;
public class Acty_Notification extends AppCompatActivity {
/**
* 创建的通知信息
*/
public TzhiInfo notiInfo;
private static final String TAG = "1Acty_Notification";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification);
ReturnBur toolbar = findViewById(R.id.topbar_tongzhixq_main);
setTitle("");
toolbar.gettitle().setText("通知编辑");
setSupportActionBar(toolbar);
initView();
}
String tzcontent;
NotificationManager notificationManager;
EditText tzbt, tznr;
long tzltzldsqlid=-1;
private void initView() {
TextView tzcjsj = findViewById(R.id.tzcjsj_tongzhixq_main),
tzgxsj = findViewById(R.id.tzgxsj_tongzhixq_main);
tzbt = findViewById(R.id.tzhibt_tongzhixq_main);
tznr = findViewById(R.id.bjtz_tonzxq_main);
notificationManager = getSystemService(NotificationManager.class);
Intent syhdInte = getIntent();
// 通知更新时间
tzgxsj.setText(formatter.format(LocalDateTime.now()));
/* //如果有这个数据就证明是跳转的,就直接不执行以下了
tzltzldsqlid= syhdInte.getLongExtra("sqlid", -1);
if (tzltzldsqlid != -1) {
Cursor query = SqlOphelper.getInstance(this).getReadDb().rawQuery("select *from yhtzjl where id=?", new String[]{String.valueOf(tzltzldsqlid)});
query.moveToNext();
notiInfo = new TzhiInfo(query.getString(1), query.getString(2), LocalDateTime.parse(query.getString(3), formatter));
notiInfo.sqlid = tzltzldsqlid;
tzcjsj.setText(query.getString(3));
tzbt.setText(notiInfo.title);
tznr.setText(notiInfo.content);
query.close();
}else {*/
positon = syhdInte.getIntExtra("dqtz", -1);
if (positon >= 0) {
notiInfo = Frm_Notifa.frm_notifa.tzsju.get(positon);
tzcjsj.setText(formatter.format(notiInfo.createTime));
tzbt.setText(notiInfo.title);
tznr.setText(notiInfo.content);
} else {
LocalDateTime nowd = LocalDateTime.now();
//新建该对象
notiInfo = new TzhiInfo(nowd, false);
tzcjsj.setText(formatter.format(nowd));
}
// }
tzcontent=notiInfo.content;
}
int positon = -1;
public static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.tzxxbjym, menu);
return true;
}
/*@Override
public void setIntent(Intent newIntent) {
super.setIntent(newIntent);
setIntent(newIntent);
}*/
/**
* 删除通知
*/
private void shanchutz(){
if (notiInfo.sqlid==-1){
UtilToast.showShortT(this,"该通知还未添加哦");
return ;
}
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("删除通知提醒").setIcon(R.drawable.senbjlogo).setMessage("确认删除吗?")
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SqlOphelper.getInstance(Acty_Notification.this).getWriteDb().delete(SqlOphelper.YHTZb, "id=?", new String[]{String.valueOf(notiInfo.sqlid)});
UtilToast.showShortT(Acty_Notification.this,"删除成功");
try {
Frm_Notifa.frm_notifa.tzsju.remove(notiInfo);
Frm_Notifa.frm_notifa.adapterTonzhilb.notifyDataSetChanged();
}catch (NullPointerException e){
Log.e(TAG, "onOptionsItemSelected: adapterTonzhilb是空对象");
}
//取消通知
notificationManager.cancel((int) notiInfo.sqlid);
//结束活动
finish();
}
});
builder.setNegativeButton("取消",null);
AlertDialog dialog = builder.create();
dialog.show();
}
/**
* 被选中的menu item监听
*
* @param item
* @return
*/
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
//删除通知,也会取消通知
case R.id.menu_sctz:
shanchutz();
break;
case R.id.menu_qxfs:
UtilToast.showShortT(this,"通知已从通知栏取消");
notificationManager.cancel((int) notiInfo.sqlid);
break;
case R.id.menu_qxtj:
sftj=false;
finish();
break;
}
return true;
}
boolean sftj=true;
/**
* 返回数据给通知fragment
*/
@Override
protected void onPause() {
super.onPause();
String tzneiron = tznr.getText().toString();
String tztitle = tzbt.getText().toString();
if (tztitle.equals("")||!sftj) return;
//有就不重复添加,就更新
if (tzltzldsqlid==-1&&positon < 0) {
Log.d(TAG, "onPause:通知添加成功" + tztitle);
notiInfo.content = tzneiron;
notiInfo.title = tztitle;
Frm_Notifa.frm_notifa.tzcjwc(notiInfo);
} else {
//一样就不更新
if (tzneiron.equals(tzcontent)){
return;
}
Log.d(TAG, "onPause: 通知修改成功");
notiInfo.updateTime = LocalDateTime.now();
notiInfo.title = tztitle;
notiInfo.content = tzneiron;
//更新数据库
SqlOphelper.getInstance(this).getWriteDb().execSQL(SqlOphelper.update, new Object[]{tztitle, tzneiron, notiInfo.sqlid});
//更新列表数据
Frm_Notifa.frm_notifa.adapterTonzhilb.notifyItemChanged(positon);
}
}
public static void startThis(Context context, int position) {
Intent intent = new Intent(context, Acty_Notification.class);
intent.putExtra("dqtz", position);
context.startActivity(intent);
}
}
通知碎片Fragment类
package abc.szj.myapps;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentValues;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import java.time.LocalDateTime;
import java.util.ArrayList;
import abc.szj.myapps.others.TzhiInfo;
import abc.szj.myapps.others.SqlOphelper;
import abc.szj.myapps.others.UtilToast;
public class Frm_Notifa extends Fragment {
public final static Frm_Notifa frm_notifa=new Frm_Notifa();
View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view= inflater.inflate(R.layout.fragment__notifa, container, false);
sqlOphelper=SqlOphelper.getInstance(view.getContext());
initview();
return view;
}
private void initview(){
Button fastz=view.findViewById(R.id.fstz_Bn_tzhi),tianjtz=view.findViewById(R.id.tjtz_Bn_tzhi);
fastz.setOnClickListener(v->{fsontzhi();});
tianjtz.setOnClickListener(v->Acty_Notification.startThis(view.getContext(),-1));
RecyclerView tzlb=view.findViewById(R.id.tzlb_RV_tzhi);
tzlb.setLayoutManager(new LinearLayoutManager(view.getContext()));
tzlb.addItemDecoration(new DividerItemDecoration(view.getContext(),DividerItemDecoration.VERTICAL));
tzsju=new ArrayList<>(6);
getSqlTzsj();
adapterTonzhilb=new AdapterTonzhilb(tzsju);
tzlb.setAdapter(adapterTonzhilb);
//设置通知渠道
setNotifiChanel();
}
private static final String TAG = "1Frm_Notifa";
SqlOphelper sqlOphelper;
/**
* 数据库通知记录数据获取
*/
public void getSqlTzsj(){
Cursor rawQuery =sqlOphelper.getReadDb().rawQuery(SqlOphelper.select, null);
while (rawQuery.moveToNext()){
TzhiInfo notiInfo=new TzhiInfo(rawQuery.getString(1),
rawQuery.getString(2),LocalDateTime.parse(rawQuery.getString(3),Acty_Notification.formatter));
notiInfo.sqlid=rawQuery.getInt(0);
tzsju.add(notiInfo);
}
rawQuery.close();
}
protected void fsontzhi(){
for (TzhiInfo notiInfo:tzsju){
//是否要发送通知
if (notiInfo.sfyfs){
//发送通知
sendTonzhi(notiInfo);
}
}
}
NotificationManager notificationManager;
public static final String tzhijudid="123";
/**
* 开辟通知渠道
*/
public void setNotifiChanel(){
notificationManager=view.getContext().getSystemService(NotificationManager.class);
NotificationChannel channel=new NotificationChannel(tzhijudid,"通知提醒",NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(channel);
}
public void sendTonzhi(TzhiInfo notiInfo){
// Intent intent=new Intent(view.getContext(),Acty_Notification.class);
// intent.putExtra("sqlid",notiInfo.sqlid);
Notification.Builder builder=new Notification.Builder(view.getContext(),tzhijudid);
builder.setContentTitle(notiInfo.title) .setContentText(notiInfo.content)
.setSmallIcon(R.drawable.notification)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.senbjlogo,null))
//常驻通知
.setOngoing(true);
// .setContentIntent(PendingIntent.getActivity(view.getContext(), (int) notiInfo.sqlid,intent,PendingIntent.FLAG_CANCEL_CURRENT));
Notification notification = builder.build();
//不可被清理掉
notification.flags=Notification.FLAG_NO_CLEAR;
UtilToast.showShortT(view.getContext(),"发送通知成功");
notificationManager.notify((int) notiInfo.sqlid,notification);
}
protected AdapterTonzhilb adapterTonzhilb;
public void tzcjwc(TzhiInfo notiInfo){
ContentValues contentValues=new ContentValues();
contentValues.put("tztitle",notiInfo.title);
contentValues.put("tzneiron",notiInfo.content);
contentValues.put("tzcjsj",Acty_Notification.formatter.format(notiInfo.createTime));
//插入数据 返回id
notiInfo.sqlid=sqlOphelper.getWriteDb().insert(SqlOphelper.YHTZb,"",contentValues);
tzsju.add(0,notiInfo);
// adapterTonzhilb.datas.add(notiInfo);
adapterTonzhilb.notifyDataSetChanged();
}
public ArrayList<TzhiInfo> tzsju;
}
笔记碎片类Fragment
package abc.szj.myapps;
import android.database.Cursor;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import abc.szj.myapps.others.NoteInfo;
import abc.szj.myapps.others.SqlOphelper;
import abc.szj.myapps.others.UtilDateTime;
/**
* A simple {@link Fragment} subclass.
* create an instance of this fragment.
*/
public class Frm_Note extends Fragment {
public static Frm_Note frm_note=new Frm_Note();
View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view=inflater.inflate(R.layout.fragment_note, container, false);
sqlOphelper=SqlOphelper.getInstance(view.getContext());
initView();
return view;
}
public AdapterNote adapterNote;
private void initView(){
RecyclerView notelb=view.findViewById(R.id.bjlb_note_RV);
notelb.setLayoutManager(new LinearLayoutManager(view.getContext()));
Button tjbj=view.findViewById(R.id.bn_tjbj_note);
tjbj.setOnClickListener(v->{
Acty_Notebiji.StartThis(view.getContext(),-1);
});
datas=new ArrayList<>(6);
getNoteSqlsj();
adapterNote=new AdapterNote(datas);
notelb.setAdapter(adapterNote);
}
public ArrayList<NoteInfo> datas;
SqlOphelper sqlOphelper;
public void getNoteSqlsj() {
Cursor cursor = sqlOphelper.getReadDb().rawQuery("select *from "+ SqlOphelper.YHBJb+" order by id desc ", null);
while (cursor.moveToNext()){
NoteInfo noteInfo=new NoteInfo(cursor.getInt(0),cursor.getString(1),cursor.getString(2),
LocalDateTime.parse(cursor.getString(3),UtilDateTime.formatter),LocalDateTime.
parse(cursor.getString(4),UtilDateTime.formatter),cursor.getInt(5),
cursor.getString(6),cursor.getInt(7),cursor.getInt(8));
datas.add(noteInfo);
}
cursor.close();
datas.sort(notePaixu);
}
public NotePaixu notePaixu=new NotePaixu();
class NotePaixu implements Comparator<NoteInfo>{
@Override
public int compare(NoteInfo o1, NoteInfo o2) {
return o1.zyx>o2.zyx?-1:1;
}
}
public void cjwc(NoteInfo noteInfo){
datas.add(0,noteInfo);
datas.sort(new Comparator<NoteInfo>() {
@Override
public int compare(NoteInfo o1, NoteInfo o2) {
return 0;
}
});
adapterNote.notifyDataSetChanged();
}
}
笔记编辑页面类
package abc.szj.myapps;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.MediaStore;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.time.LocalDateTime;
import abc.szj.myapps.others.NoteInfo;
import abc.szj.myapps.others.ReturnBur;
import abc.szj.myapps.others.SqlOphelper;
import abc.szj.myapps.others.UtilDateTime;
import abc.szj.myapps.others.UtilToast;
import top.defaults.colorpicker.ColorPickerPopup;
public class Acty_Notebiji extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notebiji);
ReturnBur bur=findViewById(R.id.rb_topb_bjbj);
setSupportActionBar(bur);
setTitle("");
bur.gettitle().setText("笔记页");
Intent intent = getIntent();
position=intent.getIntExtra("index",-1);
initZhuneiron();
}
int position;
EditText et_bjbt, bj_bjnr;
String bjpath;
private void initZhuneiron(){
ImageButton shareB=findViewById(R.id.ib_share_bjbj);
shareB.setOnClickListener(v->shareBji(shareB));
TextView cjsj=findViewById(R.id.cjsj_tv_bjbj);
TextView gxsj=findViewById(R.id.gxsj_tv_bjbj);
//主内容,用来设置背景,以及生成分享的图片
zhunron=findViewById(R.id.ll_content_bjbj);
et_bjbt =findViewById(R.id.bt_et_bjbj);
bj_bjnr =findViewById(R.id.nr_et_bjbj);
if (position>=0){
noteInfo= Frm_Note.frm_note.datas.get(position);
cjsj.setText(UtilDateTime.formatter.format(noteInfo.cjsj));
bj_bjnr.setText(noteInfo.neir);
bj_bjnr.setTextSize(noteInfo.nrztdx);
et_bjbt.setTextSize(noteInfo.nrztdx+6);
shezhiBijibjtp();
bjpath=noteInfo.bjbjtlj;
Log.d(TAG, "initZhuneiron: "+noteInfo.bjbjtlj);
try {
yszsfgg=noteInfo.bjnrys;
et_bjbt.setTextColor(yszsfgg);
bj_bjnr.setTextColor(yszsfgg);
/* //设置颜色
et_bjbt.setTextColor(Color.parseColor(noteInfo.bjnrys));
bj_bjnr.setTextColor(Color.parseColor(noteInfo.bjnrys));*/
}catch (Exception e){
Log.d(TAG, "颜色为空 initZhuneiron: "+noteInfo.bjnrys);
}
bijicontent=noteInfo.biaot+noteInfo.neir;
et_bjbt.setText(noteInfo.biaot);
gxsj.setText(UtilDateTime.formatter.format(noteInfo.gxsj));
}else {
noteInfo=new NoteInfo(0,UtilDateTime.getNow());
cjsj.setText(UtilDateTime.formatter.format(UtilDateTime.getNow()));
gxsj.setText(UtilDateTime.formatter.format(LocalDateTime.now()));
}
bj_bjnr.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
gxsj.setText(UtilDateTime.formatter.format(UtilDateTime.getNow()));
noteInfo.neir=s.toString();
}
});
dqnrzh=noteInfo.nrztdx;
dqbtzh=dqnrzh+6;
// //小于安卓10申请权限
// if (Build.VERSION.SDK_INT<Build.VERSION_CODES.Q){
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE},qingqiuxiePrim);
// }
}
String bijicontent;
NoteInfo noteInfo;
LinearLayout zhunron;
/**分享笔记*/
protected void shareBji(View view){
Bitmap bitmap= Bitmap.createBitmap(zhunron.getWidth(), zhunron.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
//防止生成透明图
c.drawColor(Color.WHITE);
zhunron.draw(c);
//弹窗视图
View popview= getLayoutInflater().inflate(R.layout.popuwindow,null,false);
PopupWindow popupWindow=new PopupWindow(popview, ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
// 设置外部区域可以点击取消popupWindow
popupWindow.setOutsideTouchable(true);
//设置焦点,以便按返回键先退出浮窗
popupWindow.setFocusable(true);
// 设置可触摸
popupWindow.setTouchable(true);
// 设置动画高度
popupWindow.setElevation(100);
Button tpfs=popview.findViewById(R.id.bn_tpfs_pop),wzfx=popview.findViewById(R.id.bn_wbfs_pop);
//保存图片或者复制文本监听
tpfs.setOnClickListener(v->{
SaveImage(bitmap);
popupWindow.dismiss();
});
wzfx.setOnClickListener(v->{
copyText(noteInfo);
popupWindow.dismiss();
});
ImageView fxdtp=popview.findViewById(R.id.iv_tpzs_pop);
fxdtp.setImageBitmap(bitmap);
popupWindow.showAsDropDown(view,0,100,Gravity.BOTTOM);
}
/**设置背景图*/
private void shezhiBijibjtp(){
Log.d(TAG, "shezhiBijibjtp: "+noteInfo.bjbjtlj);
if (noteInfo.bjbjtlj==null||noteInfo.bjbjtlj.equals("")){
return;
}
new Thread(()->{
Log.d(TAG, "shezhiBijibjtp: "+noteInfo.bjbjtlj);
drawable=BitmapDrawable.createFromPath(noteInfo.bjbjtlj);
handler.sendEmptyMessage(13);
}).start();
}
Drawable drawable;
int yszsfgg=-16777216;
private void shezhiwenbys(){
//用的颜色选择器库依赖 implementation 'com.github.duanhong169:colorpicker:1.1.6'
/*AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("字体颜色输入#ffffffff,前两位不透明度,后六位对应rgb值,或者颜色英文名");
EditText yssr=new EditText(this);
//设置条件
yssr.setFilters(new InputFilter[]{new InputFilter.LengthFilter(10)});
yssr.setText(noteInfo.bjnrys);
builder.setView(yssr);
builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
String valu=yssr.getText().toString();
noteInfo.bjnrys=valu;
et_bjbt.setTextColor(Color.parseColor(valu));
bj_bjnr.setTextColor(Color.parseColor(valu));
dialog.dismiss();
}catch (Exception e){
UtilToast.showShortT(Acty_Notebiji.this,"请按规范输入颜色值");
return;
}
}
});
builder.setNegativeButton("取消",null);
AlertDialog dialog = builder.create();
dialog.show();*/
new ColorPickerPopup.Builder(this)
.initialColor(noteInfo.bjnrys).enableAlpha(true)
.okTitle("确认").cancelTitle("取消").showValue(true).build().show(new ColorPickerPopup.ColorPickerObserver() {
@Override
public void onColorPicked(int color) {
Log.d(TAG, "colorChanged: "+color);
noteInfo.bjnrys= color;
bj_bjnr.setTextColor(color);
et_bjbt.setTextColor(color);
}
});
}
public static final int qingqiuxiePrim=123;
public void SaveImage(Bitmap bitmap){
//保存图片
new Thread(()->{
Uri bcuri=getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,new ContentValues());
if (TextUtils.isEmpty(bcuri.toString())){
handler.sendEmptyMessage(11);
return ;
}
try {
OutputStream outputStream=getContentResolver().openOutputStream(bcuri);
if (bitmap.compress(Bitmap.CompressFormat.PNG,100,outputStream)){
handler.sendEmptyMessage(12);
}else {
handler.sendEmptyMessage(11);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}).start();
}
Handler handler=new Handler(Looper.getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
switch (msg.what){
case 12:
UtilToast.showShortT(Acty_Notebiji.this,"保存成功");
break;
case 11:
UtilToast.showShortT(Acty_Notebiji.this,"保存失败");
case 13:
zhunron.setBackground(drawable);
}
return true;
}
});
/**
* 实现文本复制功能
*
* @param noteInfo 复制的笔记
* */
public void copyText(NoteInfo noteInfo) {
if (!TextUtils.isEmpty(noteInfo.neir)) {
// 得到剪贴板管理器
ClipboardManager cmb = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
// 创建一个剪贴数据集,包含一个普通文本数据条目(需要复制的数据)
ClipData clipData = ClipData.newPlainText("笔记分享", noteInfo.toString());
// 把数据集设置(复制)到剪贴板
cmb.setPrimaryClip(clipData);
// Only show a toast for Android 12 and lower.
if (Build.VERSION.SDK_INT <= 32){
UtilToast.showShortT(this,"笔记复制成功");
}
}
}
private static final String TAG = "1Acty_Notebiji";
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case qingqiuxiePrim:
if (grantResults[0]!= PackageManager.PERMISSION_GRANTED)UtilToast.showShortT(this,"无权限,将无法保存图片,修改背景等,建议去设置中开启该应用的权限");
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
String bijinr = bj_bjnr.getText().toString();
String bjibt = et_bjbt.getText().toString();
//如果选了取消或者为空就返回
if (bjibt.equals("")||sfqx) return;
noteInfo.nrztdx= (int) dqnrzh;
noteInfo.biaot = bjibt;
noteInfo.neir = bijinr;
noteInfo.gxsj=UtilDateTime.getNow();
//有就不重复添加,就更新
if (position < 0) {
Log.d(TAG, "onPause:通知添加成功" + bjibt);
UtilToast.showShortT(this,"创建成功");
ContentValues contentValues=new ContentValues();
contentValues.put("bjtitle",bjibt);
contentValues.put("bjneiron",bijinr);
contentValues.put("bjcjsj",UtilDateTime.formatter.format(noteInfo.cjsj));
contentValues.put("bjgxsj",UtilDateTime.formatter.format(noteInfo.gxsj));
contentValues.put("zyxdj",noteInfo.zyx);
contentValues.put("bjbjt",noteInfo.bjbjtlj);
contentValues.put("bjnrys",noteInfo.bjnrys);
contentValues.put("nrztdx",noteInfo.nrztdx);
noteInfo.sqlid=SqlOphelper.getInstance(this).getWriteDb().insert(SqlOphelper.YHBJb,"",contentValues);
Log.d(TAG, "onPause: "+noteInfo.sqlid);
Frm_Note.frm_note.cjwc(noteInfo);
} else {
//一样就不更新
if ((bjibt+bijinr).equals(bijicontent)) {
if (noteInfo.bjbjtlj==null||noteInfo.bjbjtlj.equals(bjpath)){
if (yszsfgg==noteInfo.bjnrys){
Log.d(TAG, "onPause: 没有更新");
return;
}
}
}
Log.d(TAG, "onPause: 笔记修改成功");
//更新数据库
SqlOphelper.getInstance(this).getWriteDb().execSQL(SqlOphelper.updatebjjl,
new Object[]{bjibt, bijinr,UtilDateTime.formatter.format(noteInfo.gxsj),noteInfo.bjbjtlj,noteInfo.bjnrys,noteInfo.nrztdx, noteInfo.sqlid});
//更新列表数据
Frm_Note.frm_note.adapterNote.notifyItemChanged(position);
Log.d(TAG, "onDestroy: 列表数据更新了");
}
Log.e(TAG, "onDestroy: bt"+bjibt+bijinr);
}
public static final int qingqiubjtp=1;
/**更改背景调用,跳转到图片选择页面*/
protected void znrbjgg(){
Intent tpxz=new Intent(Intent.ACTION_PICK);
tpxz.setType("image/*");
startActivityForResult(tpxz,qingqiubjtp);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//请求图片成功
if (requestCode==qingqiubjtp&&data!=null){
Uri selectedImage = data.getData();//返回的是uri
String [] filePathColumn ={MediaStore.Images.Media.DATA} ;
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
//背景图路径
noteInfo.bjbjtlj = cursor.getString(columnIndex);
shezhiBijibjtp();
Log.d(TAG, "onActivityResult:图片链接 "+noteInfo.bjbjtlj);
UtilToast.showShortT(this,"图片获取成功");
cursor.close();
}else{
UtilToast.showShortT(this,"图片获取失败"+data);
Log.d(TAG, "onActivityResult: "+data);
}
}
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
getMenuInflater().inflate(R.menu.bjgncd,menu);
return true;
}
float dqnrzh;
float dqbtzh;
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
//更改背景图片
case R.id.bjbj_item:
znrbjgg();
break;
case R.id.bjztys_item:
shezhiwenbys();
break;
//字号增大减小
case R.id.zdzh_item:
et_bjbt.setTextSize(dqbtzh+=5);
bj_bjnr.setTextSize(dqnrzh+=5);
UtilToast.showShortT(this,"当前标题字号"+dqbtzh+"当前内容字号"+dqnrzh);
break;
case R.id.jxzh_item:
UtilToast.showShortT(this,"当前标题字号"+dqbtzh+"当前内容字号"+dqnrzh);
et_bjbt.setTextSize(dqbtzh-=5);
bj_bjnr.setTextSize(dqnrzh-=5);
break;
case R.id.qxtjbj_item:
sfqx=true;
finish();
break;
case R.id.scbj_item:
shanchubiji();
break;
}
return true;
}
boolean sfqx=false;
/**
* 删除笔记
*/
private void shanchubiji(){
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("删除笔记提醒").setIcon(R.drawable.senbjlogo).setMessage("确认删除吗?")
.setPositiveButton("确认", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
SqlOphelper.getInstance(Acty_Notebiji.this).getWriteDb().delete(SqlOphelper.YHBJb,"id=?",new String[]{String.valueOf(noteInfo.sqlid)});
Frm_Note.frm_note.datas.remove(noteInfo);
Frm_Note.frm_note.adapterNote.notifyDataSetChanged();
finish();
}
});
builder.setNegativeButton("取消",null);
//显示确认框
builder.create().show();
}
public static void StartThis(Context context, int positon){
Intent intent=new Intent(context,Acty_Notebiji.class);
intent.putExtra("index",positon);
context.startActivity(intent);
}
}
主活动 用来显示两个碎片
package abc.szj.myapps;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager.widget.ViewPager;
import java.util.ArrayList;
import abc.szj.myapps.others.UtilToast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar=findViewById(R.id.main_topbar_Tb);
toolbar.setTitle("森笔记");
setSupportActionBar(toolbar);
initview();
}
private static final String TAG = "1MainActivity";
private void initview(){
RadioGroup navgroup=findViewById(R.id.navzu_main_RG);
RadioButton tonzhi= (RadioButton) navgroup.getChildAt(0);
RadioButton biji= (RadioButton) navgroup.getChildAt(1);
ViewPager viewPager=findViewById(R.id.main_showFragm_vp);
ArrayList<Fragment> fragments=new ArrayList<>(2);
fragments.add(Frm_Notifa.frm_notifa);
fragments.add(Frm_Note.frm_note);
viewPager.setAdapter(new AdapterFragmentPager(getSupportFragmentManager(),fragments));
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
switch (position){
case 0:
tonzhi.setChecked(true);
break;
case 1:
biji.setChecked(true);
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
tonzhi.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked){
viewPager.setCurrentItem(0);
}else {
viewPager.setCurrentItem(1);
}
}
});
}
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
getMenuInflater().inflate(R.menu.mainmenu,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.shiyonjc_main:
ActyShiyongjc.startThis(this);
break;
case R.id.qita_main:
UtilToast.showShortT(this,"敬请期待!");
}
return super.onOptionsItemSelected(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="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/main_topbar_Tb"
android:layout_width="match_parent"
app:titleTextColor="@color/blue_200"
android:textAlignment="center"
android:layout_height="39dp"/>
<androidx.viewpager.widget.ViewPager
android:layout_weight="1"
android:id="@+id/main_showFragm_vp"
android:layout_width="match_parent"
android:layout_height="0dp"/>
<RadioGroup
android:id="@+id/navzu_main_RG"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioButton
android:paddingTop="6dp"
android:gravity="center"
android:button="@null"
android:layout_weight="1"
android:id="@+id/tonz_main_RB"
android:layout_width="0dp"
android:text="通知"
android:drawableTop="@drawable/notification"
android:background="@drawable/navbar"
android:checked="true"
android:paddingBottom="6dp"
android:layout_height="wrap_content"/>
<RadioButton
android:paddingTop="6dp"
android:layout_weight="1"
android:id="@+id/biji_main_RB"
android:layout_width="0dp"
android:text="笔记"
android:drawableTop="@drawable/ic_baseline_event_note_24"
android:background="@drawable/navbar"
android:gravity="center"
android:layout_height="wrap_content"
android:button="@null"
android:paddingBottom="6dp" />
</RadioGroup>
</LinearLayout>