赞
踩
{
@Override
public void onClick(DialogInterface dialog, int which)
{
Toast.makeText(ContentActivity.this, “选择的背景色为:” + colors[which], Toast.LENGTH_SHORT).show();
switch (which){
case 0:
new NoteManager(mContext).updateBackground(title,“#C7EDCC”);
onResume();
break;
case 1:
new NoteManager(mContext).updateBackground(title,“#E6E6FA”);
onResume();
break;
case 2:
new NoteManager(mContext).updateBackground(title,“#FC9D9A”);
onResume();
break;
default:
break;
}
}
});
builder.show();
}
});
该功能的实现思路为,为闹钟设置闹铃后,在该记事条目对应得ContentActvity的右上角会显示闹铃的时间,长按该闹铃时间戳则可删除该闹铃,同时闹铃到达指定时间后,会在程序中弹出提示框并且在手机通知栏也会有消息提醒。功能截图如下:
| 设置闹钟 | 闹钟设置完成 | 通知栏响应 |
| — | — | — |
| | | |
首先是闹铃时间的设定,这里要对ContentActivity实现相应的设置日期时间的接口。
public class ContentActivity extends AppCompatActivity
implements DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener{
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
alarm_year=year;
alarm_month=monthOfYear+1;
alarm_day=dayOfMonth;
}
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
alarm_hour=hourOfDay;
alarm_minute=minute;
alarm=alarm_year+“/”+alarm_month+“/”+alarm_day+" “+alarm_hour+”:"+alarm_minute;
av.setText(“Alert at “+alarm+”!”);
av.setVisibility(View.VISIBLE);
Log.d(“ContentActivity”,“alarm”+alarm);
new NoteManager(mContext).updateAlarm(title,alarm);
loadAlarm(alarm, title, 0);
Toast.makeText(this,“Alarm will be on at “+alarm+” !”,Toast.LENGTH_LONG).show();
}
}
接着就是开始设置闹铃:
public void setAlarm(View v) {
if(alarm.length()<=1) {
//if no alarm clock has been set up before
//show the current time
Calendar c=Calendar.getInstance();
alarm_hour=c.get(Calendar.HOUR_OF_DAY);
alarm_minute=c.get(Calendar.MINUTE);
alarm_year=c.get(Calendar.YEAR);
alarm_month=c.get(Calendar.MONTH)+1;
alarm_day=c.get(Calendar.DAY_OF_MONTH);
}
else {
//show the alarm clock time which has been set up before
int i=0, k=0;
while(i<alarm.length()&&alarm.charAt(i)!=‘/’) i++;
alarm_year=Integer.parseInt(alarm.substring(k,i));
k=i+1;i++;
while(i<alarm.length()&&alarm.charAt(i)!=‘/’) i++;
alarm_month=Integer.parseInt(alarm.substring(k,i));
k=i+1;i++;
while(i<alarm.length()&&alarm.charAt(i)!=’ ') i++;
alarm_day=Integer.parseInt(alarm.substring(k,i));
k=i+1;i++;
while(i<alarm.length()&&alarm.charAt(i)!=‘:’) i++;
alarm_hour=Integer.parseInt(alarm.substring(k,i));
k=i+1;i++;
alarm_minute=Integer.parseInt(alarm.substring(k));
}
new TimePickerDialog(this,this,alarm_hour,alarm_minute,true).show();
new DatePickerDialog(this,this,alarm_year,alarm_month-1,alarm_day).show();
}
同样的,监听该view,若被响应则调用onResume();
长按删除闹铃功能这里就不再赘述了,接下来来详细讲解如何调用通知栏的通知功能。部分关键代码:
private void loadAlarm(String alarm, String title, int days) {
int alarm_hour=0;
int alarm_minute=0;
int alarm_year=0;
int alarm_month=0;
int alarm_day=0;
int i=0, k=0;
while(i<alarm.length()&&alarm.charAt(i)!=‘/’) i++;
alarm_year=Integer.parseInt(alarm.substring(k,i));
k=i+1;i++;
while(i<alarm.length()&&alarm.charAt(i)!=‘/’) i++;
alarm_month=Integer.parseInt(alarm.substring(k,i));
k=i+1;i++;
while(i<alarm.length()&&alarm.charAt(i)!=’ ') i++;
alarm_day=Integer.parseInt(alarm.substring(k,i));
k=i+1;i++;
while(i<alarm.length()&&alarm.charAt(i)!=‘:’) i++;
alarm_hour=Integer.parseInt(alarm.substring(k,i));
k=i+1;i++;
alarm_minute=Integer.parseInt(alarm.substring(k));
Intent intent = new Intent(ContentActivity.this, OneShotAlarm.class);
intent.putExtra(“alarm_title”,title);
PendingIntent sender = PendingIntent.getBroadcast(
ContentActivity.this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
Calendar alarm_time = Calendar.getInstance();
alarm_time.set(alarm_year,alarm_month-1,alarm_day,alarm_hour,alarm_minute);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, alarm_time.getTimeInMillis(), sender);
}
在上述关键代码中,可以看到在loadAlarm函数中使用了Intent来传递闹铃时间的消息给OneShotAlarm类,且是再闹铃设置完成后,构建一个PendingIntent广播,通过AlarmManager在时间到达指定的闹铃事件后,发出广播,接收到广播的OneShotAlarm类做出回应,在通知栏显示通知。
这里要先在AndroidManifest.xml设置广播接收器:
<receiver
android:name=“.utils.OneShotAlarm”
android:process=“:remote” />
接下来让我们看看OneShortAlarm类,当OneShotAlarm收到广播后,则构建通知消息并在通知栏显示。同时该类中设置了通知消息显示的内容,有该记事本程序名,记事条目的标题,该记事创建时间戳以及记事内容。通过构造Notification类实现该消息。部分关键代码如下:
public class OneShotAlarm extends BroadcastReceiver {
private String alarm_title;
@Override
public void onReceive(Context context, Intent intent) {
alarm_title=intent.getStringExtra(“alarm_title”);
Toast.makeText(context,“Time UP!”,Toast.LENGTH_LONG).show();
Vibrator vb =(Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
vb.vibrate(300);
showNotice(context);
}
private void showNotice(Context context) {
Intent intent=new Intent(context,ContentActivity.class);
Note record = new NoteManager(context).get(alarm_title);
new NoteManager(context).deleteAlarm(alarm_title);
PendingIntent pi=PendingIntent.getActivity(context,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager manager=(NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
Notification notification=new NotificationCompat.Builder(context)
.setContentTitle(record.getCreate_date())
.setContentText(record.getText())
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.drawable.icon))
.setContentIntent(pi)
.setAutoCancel(true)
//.setStyle(new NotificationCompat.BigTextStyle().bigText(record.getMainText()))
.setLights(Color.GREEN,1000,1000)
.build();
manager.notify(0,notification);
}
}
在早先就有了解到一些动态搜索框现成的源码,这里则使用了一些网上开源的搜索框控件的使用。
首先需要添加第三方依赖,'com.quinny898.library.persistentsearch:library:1.1.0-SNAPSHOT’就可以使用了。该搜索框还支持语音输入识别,但这里因为在设计时并没有考虑语音识别功能,所以这里就弃用了该功能。
附上功能截图:
<com.quinny898.library.persistentsearch.SearchBox
android:layout_width=“wrap_content”
android:id=“@+id/searchbox”
android:layout_height=“wrap_content”/>
设置完成后,需要对显示搜索到的记事条目,内容,及搜索到的记事条目总和进行显示,这里布局设计如下:
<LinearLayout
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:orientation=“vertical”>
<ListView
android:id=“@+id/history_lis_search”
android:layout_marginLeft=“20dp”
android:layout_marginRight=“20dp”
android:layout_marginBottom=“5dp”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:background=“@drawable/border_bottom_null”>
<ListView
android:id=“@+id/content_lis_search”
android:layout_marginLeft=“20dp”
android:layout_marginRight=“20dp”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:background=“@drawable/border_bottom_null”>
<TextView
android:id=“@+id/bottom_search”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_marginTop=“10dp”
android:gravity=“center_horizontal” />
接着则是代码的实现,实现该功能代码网上有很多现成的实例,这里实现起来并没有看起来的那么复杂,稍微学习后则可写出自己想要的代码:
public class SearchActivity extends AppCompatActivity {
private Context mContext;
private SearchBox sbSearch;
private TextView tvBottom;
//数据列表
private List listSearch;
//结果列表
private List listResult;
private ListView mSearchResult ;
private SearchAdapter mResultAdapter ;
private ListView mHistory ;
private HistoryAdapter mHistoryAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
mContext = this;
bindViews();
}
@Override
protected void onResume() {
super.onResume();
initData();
init();
initSearchView();
initHistory();
updateBottom();
}
private void initData() {
//本地可供检索数据获取,每次resume就要重新渲染
listSearch = new NoteManager(mContext).getNoteList();
}
private void bindViews() {
mSearchResult = (ListView) findViewById(R.id.content_lis_search);
sbSearch = (SearchBox) findViewById(R.id.searchbox);
tvBottom = (TextView) findViewById(R.id.bottom_search);
mHistory = (ListView) findViewById(R.id.history_lis_search);
}
public void init(){
listResult = new ArrayList<>();
mResultAdapter = new SearchAdapter(SearchActivity.this, listResult);
mSearchResult.setAdapter(mResultAdapter);
mSearchResult.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
manageKeyBoard();
NoteManager noteManager=new NoteManager(mContext);
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
boolean isOpen = imm.isActive();
if (isOpen) imm.hideSoftInputFromWindow(view.getWindowToken(), 0); //强制隐藏键盘
noteManager.ItemClick(listResult.get(position));
}
});
}
private void initSearchView(){
sbSearch.enableVoiceRecognition(this);
sbSearch.setMenuListener(new SearchBox.MenuListener(){
@Override
public void onMenuClick() {
reBack();
}
});
sbSearch.setSearchListener(new SearchBox.SearchListener(){
@Override
public void onSearchOpened() {
//Use this to tint the screen
}
@Override
public void onSearchClosed() {
//Use this to un-tint the screen
}
@Override
public void onSearchTermChanged(String term) {
search(term);
updateBottom();
if(listResult.size()==0){
mHistory.setVisibility(View.VISIBLE);
}else {
mHistory.setVisibility(View.GONE);
}
}
@Override
public void onSearch(String searchTerm) {
search(searchTerm);
saveHistory(searchTerm);
initHistory();
updateBottom();
}
@Override
public void onResultClick(SearchResult result) {
//React to a result being clicked
}
@Override
public void onSearchCleared() {
//Called when the clear button is clicked
}
});
}
private void initHistory(){
final List history = getHistory();
mHistoryAdapter = new HistoryAdapter(SearchActivity.this,history);
mHistory.setAdapter(mHistoryAdapter);
mHistory.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
sbSearch.populateEditText(history.get(position));
sbSearch.setSearchString(history.get(position));
}
});
}
private void search(String newText){
//若搜索内容为空
if(newText.isEmpty()){
listResult.clear();
}
else{
for (Note note : listSearch) {//开始搜索
//搜索内容搜索到相关
if (note.getTitle().contains(newText) || note.getText().contains(newText)) {
if(listResult.indexOf(note)==-1) {//且 结果集内不含有此内容
listResult.add(note);
}
}else{
//搜索内容搜索不到相关 检测是否之前有加入结果集 有则删除
if(listResult.indexOf(note)!=-1) {
listResult.remove(note);
}
}
}
}
mResultAdapter.notifyDataSetChanged();
}
private ArrayList getHistory() {
SharedPreferences reader = getSharedPreferences(“history”, MODE_PRIVATE);
String data = reader.getString(“data_history”, “”);
ArrayList history = new ArrayList<>();
String [] get= data.split(“\|”);
for( String str:get){
if(! history.contains(str) && !StringUtil.isEmpty(str)){
history.add(str);
}
}
return history;
}
private void saveHistory(String s){
StringBuilder sb = new StringBuilder();
SharedPreferences.Editor editor = getSharedPreferences(“history”,MODE_PRIVATE).edit();
for (String str: getHistory()){
sb.append(str);
sb.append(“|”);
}
sb.append(s);
editor.putString(“data_history”,sb.toString());
editor.apply();
}
private void updateBottom(){
if(sbSearch.getSearchText().trim().isEmpty()){
gone_Bottom();
return;
}
tvBottom.setVisibility(View.VISIBLE);
tvBottom.setText(“找到了 “+ listResult.size() +” 条记录”);
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
VISIBLE);
tvBottom.setText(“找到了 “+ listResult.size() +” 条记录”);
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-MAMPq5pw-1711742930843)]
[外链图片转存中…(img-ePfpZjPR-1711742930843)]
[外链图片转存中…(img-Mj96TPZT-1711742930844)]
[外链图片转存中…(img-lF3BAuxd-1711742930844)]
[外链图片转存中…(img-Cgz9Uc8p-1711742930844)]
[外链图片转存中…(img-ShW1APXe-1711742930845)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-ly9y1NlT-1711742930845)]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。