目录

1. 前言

2. 记事本功能需求

3. 部分关键代码解析及程序截图

3.1 记事本类的基本设计

3.2 记事本的数据存储设计

3.3 主界面的设计

3.4 记事本的编辑

3.5 记事本的背景色设置

3.6 记事本的闹铃功能

3.7 高级搜索

4. 总结


1. 前言

在学习安卓开发这门课程中期,学会了安卓开发的基本知识,比如,UI组件的应用,Intent的应用等等,同时期中作业为编写一个记事本程序,基于google的记事本demo, 但对于我本人来说,我更喜欢对代码从头到位都有自己的参与,于是我决定自己从头编写一个基本记事本的开发和记事本的相关扩展功能。

开发环境: Android Studio (API25以上)

2. 记事本功能需求

功能名称 功能概述 优先级
记事本基本功能 对记事本的增删改 最高
时间戳显示 记事本的最近编辑时间的显示
高级搜索 对记事本的查找
UI美化 对用户界面的美化
记事本背景色的设置 记事本背景色的设置
记事本闹钟设置 记事本的闹钟功能设置

3. 部分关键代码解析及程序截图

3.1 记事本类的基本设计

Note.java

//序列化便于本地存储
public class Note  implements Serializable,Comparable{private String title;private String create_date;private String update_date;private String text;private String background;private String date_alarm;public Note(String title,String text) {//标题this.title = title;//创建日期this.create_date = new SimpleDateFormat("yyyy-MM-dd HH-mm").format(new Date());//更新日期this.update_date = this.create_date;//内容this.text = text;//背景色this.background = null;//闹钟日期this.date_alarm = "";}
}

3.2 记事本的数据存储设计

这里由于我当时暂未学习到SQLite的数据存储方式,采用了文件读写的方式来存储记事本的条目。

首先,在AndroidManifest.xml中设置允许程序读写文件的权限。

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.VIBRATE" />

将Note存储在哈希表内,再将哈希表的内容写入文件中,同时文件存储在内置的SD卡的路径下。

NoteManager.java

public class NoteManager {private Context mContext;private List<Note> list;private String root_file;public NoteManager(Context context){root_file = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"NoteList";this.mContext = context;list = getNoteList();}//更新当前notes列表public void updateNoteList(List<Note> now_data){try {File file = new File(root_file);if (!file.exists()){file.createNewFile();}ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(root_file));oos.writeObject(now_data);oos.close();}catch (Exception e1){e1.printStackTrace();}}
}

3.3 主界面的设计

为了更好的用户体验,决定将用户设计设计成两种情况,一种为用户程序中暂无存储记事文件的情况下,一种为程序中已存有记事文件下。附上部分关键代码以及程序截图。

主界面-1 主界面-2
//检查数据列表是否为空,如果为空,那么渲染blank_Viewpublic void emptyListCheck(){int number = 0;if(data!=null){number=data.size();}if(number == 0) {smlvMain.setVisibility(View.GONE);RelativeLayout empty = (RelativeLayout) findViewById(R.id.blank_view);empty.setVisibility(View.VISIBLE);fabMenu.setVisibility(View.VISIBLE);}else{smlvMain.setVisibility(View.VISIBLE);RelativeLayout empty = (RelativeLayout) findViewById(R.id.blank_view);empty.setVisibility(View.GONE);}}

这里设置了Note条目的菜单模块和空白模块,若数据列表为空,则隐藏条目菜单模块,显示空白模块,若不为空,则隐藏空白模块,显示菜单模块。

3.4 记事本的编辑

可以看到在主界面的右下角存在一个浮动窗口菜单,这里涉及到第三方依赖的添加:

com.getbase.floatingactionbutton.FloatingActionButton

res/layout/activity_main.xml

<com.getbase.floatingactionbutton.FloatingActionsMenuadroid:id="@+id/fab_menu"adroid:layout_width="wrap_content"adroid:layout_height="wrap_content"adroid:layout_alignParentRight="true"adroid:layout_alignParentBottom="true"fab:fab_labelStyle="@style/fab_label_style"app:fab_addButtonSize="mini"fab:fab_addButtonColorNormal="#5e96b9"fab:fab_addButtonColorPressed="@null"fab:fab_addButtonPlusIconColor="@color/black"adroid:layout_marginBottom="16dp"adroid:layout_marginRight="16dp"><com.getbase.floatingactionbutton.FloatingActionButtonadroid:id="@+id/fab_add"adroid:layout_width="wrap_content"adroid:layout_height="wrap_content"fab:fab_colorNormal="@color/white"fab:fab_colorPressed="@color/green"fab:fab_title="新备忘录"fab:fab_size="mini"fab:fab_icon="@drawable/fab_add" /><com.getbase.floatingactionbutton.FloatingActionButtonadroid:id="@+id/fab_exit"adroid:layout_width="wrap_content"adroid:layout_height="wrap_content"fab:fab_colorNormal="@color/white"fab:fab_colorPressed="@color/green"fab:fab_title="退出应用"fab:fab_size="mini"app:fab_icon="@drawable/fab_exit" />
</com.getbase.floatingactionbutton.FloatingActionsMenu>

这里可以看到对浮动菜单栏的xml设计,包含两种功能,新建Note和应用的退出,涉及到功能的逻辑代码这里就不赘述了。

新建Note后,可在主界面-2下的点击Note条目或左滑条目进入编辑模式。

编辑模式-1 编辑模式-2

同时可以注意到两者编辑模式略有不同,在编辑模式-1下,可以做到修改,删除,背景色的设置,闹铃的添加,在编辑模式-2下仅仅能做到修改和删除。

左滑Note条目左滑部分关键代码:

首先需要新建一个滑动view类

public class MyScrollView extends ScrollView {private ScrollViewListener scrollViewListener = null;public MyScrollView(Context context) {super(context);}public MyScrollView(Context context, AttributeSet attrs,int defStyle) {super(context, attrs, defStyle);}public MyScrollView(Context context, AttributeSet attrs) {super(context, attrs);}public void setOnScrollListener(ScrollViewListener scrollViewListener) {this.scrollViewListener = scrollViewListener;}@Overrideprotected void onScrollChanged(int x, int y, int oldx, int oldy) {super.onScrollChanged(x, y, oldx, oldy);if (scrollViewListener != null) {if (oldy < y && ((y - oldy) > 15)) {scrollViewListener.onScroll(y - oldy);} else if (oldy > y && (oldy - y) > 15) {scrollViewListener.onScroll(y - oldy);}}}
//这一部分参考了github某个开源项目public  interface ScrollViewListener{//dy Y轴滑动距离void onScroll(int dy);}
}

设置完毕后在xml文件中即可设置应用:

<com.zc.memo.view.MyScrollViewadroid:id="@+id/sv_main"adroid:layout_width="match_parent"adroid:layout_height="wrap_content"adroid:background="@drawable/border_bottom_null"><LinearLayoutadroid:layout_width="match_parent"adroid:layout_height="wrap_content"adroid:orientation="vertical"><com.baoyz.swipemenulistview.SwipeMenuListViewadroid:id="@+id/smlv_main"adroid:layout_width="match_parent"adroid:layout_height="match_parent"adroid:descendantFocusability="blocksDescendants"adroid:divider="@color/little_gray"adroid:dividerHeight="1dp"adroid:background="@null"/></LinearLayout>
</com.zc.memo.view.MyScrollView>

接着在activity中,初始化滑动窗口及滑动窗口菜单。

 private void initView() {data = new NoteManager(context).getNoteList();smlvMain.setAdapter(new NoteAdapter(context,data));smlvMain.setMenuCreator(new MySwipeMenuCreator(context));smlvMain.setSwipeDirection(SwipeMenuListView.DIRECTION_LEFT);new ListViewUtil().setListViewHeightBasedOnChildren(smlvMain);svMain.setOnScrollListener(new MyScrollView.ScrollViewListener() {@Overridepublic void onScroll(int dy) {if (dy > 0) {//下滑showOrHideFab(false);} else if (dy <= 0 ) {//上滑showOrHideFab(true);}}});viewListener();emptyListCheck();}

这里仅放上如何初始化滑动窗口的view,关于监听这个滑动窗口的逻辑代码在这里就不赘述了。

接下来讲一讲自定义NoteAdapter适配器来展示即使条目,首先继承BaseAdapter实现一个抽象类MyBaseAdapter<T>该类可读取List列表的数据。

public abstract class MyBaseAdapter<T> extends BaseAdapter {Context context;List<T> data;public MyBaseAdapter(Context context, List<T> data) {this.context = context;this.data = data;}@Overridepublic Object getItem(int i) {return null;}@Overridepublic long getItemId(int i) {return 0;}@Overridepublic int getCount() {if(data==null) return 0;return data.size();}
}

接着在编写NoteAdapter类继承上类,初始化view, 将Note条目的各项信息展示出来,其中还自定义了一个viewHolder类,方便对xml文件中的各项组件进行绑定编辑。

public class NoteAdapter extends MyBaseAdapter<Note> {public NoteAdapter(Context context, List<Note> data) {super(context, data);}@Overridepublic View getView(int i, View view, ViewGroup viewGroup) {ViewHolder viewHolder;if(view==null){viewHolder=new ViewHolder();LayoutInflater inflater = LayoutInflater.from(context);view = inflater.inflate(R.layout.item_main_list, viewGroup, false);viewHolder.tv_lv_month = (TextView) view.findViewById(R.id.tv_lv_month);viewHolder.tv_lv_day= (TextView) view.findViewById(R.id.tv_lv_day);viewHolder.tv_lv_title = (TextView) view.findViewById(R.id.tv_lv_title);viewHolder.tv_lv_content = (TextView) view.findViewById(R.id.tv_lv_content);viewHolder.layout = (LinearLayout) view.findViewById(R.id.Linelayout);view.setTag(viewHolder);}else{viewHolder = (ViewHolder) view.getTag();}viewHolder.tv_lv_month.setText(data.get(i).getUpdate_date().split("-")[1]);viewHolder.tv_lv_day.setText(data.get(i).getUpdate_date().split("-")[2]);viewHolder.tv_lv_title.setText(data.get(i).getTitle());viewHolder.tv_lv_content.setText(data.get(i).getText());if(data.get(i).getBackground()!=null){viewHolder.layout.setBackgroundColor(Color.parseColor(data.get(i).getBackground()));}return view;}class ViewHolder{TextView tv_lv_month;TextView tv_lv_day;TextView tv_lv_title;TextView tv_lv_content;LinearLayout layout;}
}

3.5 记事本的背景色设置

进入到上述提到的编辑模式2中,也就是ContentActivity中,在其底部设置更改背景色功能。这里运用到了会话框的弹出AlertDialog。设置三种颜色。点击确认后,更改数据文件中相应记事条目Note的Background属性。接着进行调用onResume();使其重新载入数据文件中的记事条目得到背景色的更改。功能截图如下:

背景选项 设置成功

部分关键代码如下:

ivSettings.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {AlertDialog.Builder builder = new AlertDialog.Builder(ContentActivity.this);builder.setIcon(R.drawable.fab_settings);builder.setTitle("选择一个背景色");//    指定下拉列表的显示数据final String[] colors = {"护眼色", "薰衣淡紫", "粉粉粉"};builder.setItems(colors, new DialogInterface.OnClickListener(){@Overridepublic 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();}});

3.6 记事本的闹铃功能

该功能的实现思路为,为闹钟设置闹铃后,在该记事条目对应得ContentActvity的右上角会显示闹铃的时间,长按该闹铃时间戳则可删除该闹铃,同时闹铃到达指定时间后,会在程序中弹出提示框并且在手机通知栏也会有消息提醒。功能截图如下:

设置闹钟 闹钟设置完成 通知栏响应

首先是闹铃时间的设定,这里要对ContentActivity实现相应的设置日期时间的接口。

public class ContentActivity extends AppCompatActivityimplements DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener{@Overridepublic void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {alarm_year=year;alarm_month=monthOfYear+1;alarm_day=dayOfMonth;}@Overridepublic 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 timeCalendar 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 beforeint 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设置广播接收器:

<receiverandroid:name=".utils.OneShotAlarm"android:process=":remote" />

接下来让我们看看OneShortAlarm类,当OneShotAlarm收到广播后,则构建通知消息并在通知栏显示。同时该类中设置了通知消息显示的内容,有该记事本程序名,记事条目的标题,该记事创建时间戳以及记事内容。通过构造Notification类实现该消息。部分关键代码如下:

public class OneShotAlarm extends BroadcastReceiver {private String alarm_title;@Overridepublic 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);}}

3.7 高级搜索

在早先就有了解到一些动态搜索框现成的源码,这里则使用了一些网上开源的搜索框控件的使用。

首先需要添加第三方依赖,'com.quinny898.library.persistentsearch:library:1.1.0-SNAPSHOT'就可以使用了。该搜索框还支持语音输入识别,但这里因为在设计时并没有考虑语音识别功能,所以这里就弃用了该功能。

附上功能截图:

<com.quinny898.library.persistentsearch.SearchBoxandroid:layout_width="wrap_content"android:id="@+id/searchbox"android:layout_height="wrap_content"/>

设置完成后,需要对显示搜索到的记事条目,内容,及搜索到的记事条目总和进行显示,这里布局设计如下:

<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><ListViewandroid: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></LinearLayout><ListViewandroid: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"></ListView><TextViewandroid: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<Note> listSearch;//结果列表private List<Note> listResult;private ListView mSearchResult ;private SearchAdapter mResultAdapter ;private ListView mHistory ;private HistoryAdapter mHistoryAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_search);mContext = this;bindViews();}@Overrideprotected 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() {@Overridepublic 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(){@Overridepublic void onMenuClick() {reBack();}});sbSearch.setSearchListener(new SearchBox.SearchListener(){@Overridepublic void onSearchOpened() {//Use this to tint the screen}@Overridepublic void onSearchClosed() {//Use this to un-tint the screen}@Overridepublic void onSearchTermChanged(String term) {search(term);updateBottom();if(listResult.size()==0){mHistory.setVisibility(View.VISIBLE);}else {mHistory.setVisibility(View.GONE);}}@Overridepublic void onSearch(String searchTerm) {search(searchTerm);saveHistory(searchTerm);initHistory();updateBottom();}@Overridepublic void onResultClick(SearchResult result) {//React to a result being clicked}@Overridepublic void onSearchCleared() {//Called when the clear button is clicked}});}private void initHistory(){final List<String> history = getHistory();mHistoryAdapter = new HistoryAdapter(SearchActivity.this,history);mHistory.setAdapter(mHistoryAdapter);mHistory.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic 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<String> getHistory() {SharedPreferences reader = getSharedPreferences("history", MODE_PRIVATE);String data = reader.getString("data_history", "");ArrayList<String> 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() +" 条记录");}private void gone_Bottom(){TextView bottom = (TextView) findViewById(R.id.bottom_search);bottom.setVisibility(View.GONE);}private void reBack(){finish();overridePendingTransition(R.anim.in_from_left, R.anim.out_from_right);}@Overridepublic boolean onKeyUp(int keyCode, KeyEvent event) {switch(keyCode){case KeyEvent.KEYCODE_BACK:finish();overridePendingTransition(R.anim.in_from_left, R.anim.out_from_right);break;}return super.onKeyUp(keyCode, event);}private void manageKeyBoard() {InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);}
}

4. 总结

这次完成该记事本的完成算是对先前学到知识的应用以及进阶,如Intent意图的使用,adapter适配器的使用,等等,对其掌握有了更进一步的提高,同时对程序UI美化和程序数据存储有了全新的了解与把握。也了解到市面上有很多开源的控件可供使用,还需要学习的东西还有很多很多。谢谢。

参考资料:

https://blog.csdn.net/zhouchen1998/article/details/83628218

https://blog.csdn.net/sf_zhang26/article/details/54803691

https://blog.csdn.net/zhouchen1998/article/details/82995526

本文作者:林嘉伟

原文链接:https://blog.csdn.net/DieForCode/article/details/90602224

Android:实现安卓小程序-记事本(备忘录)的开发相关推荐

  1. 一款功能强大的客户端研发助手,适用于 iOS 、Android、微信小程序 !移动端开发必备...

    热文推荐: 尘埃落定!清华才子王垠加入华为职级22,前阿里P10赵海平加入字节跳动,职级或为4+ 百度网盘"破解版",Pandownload开发者被抓 DoraemonKit 简称 ...

  2. 基于安卓android和微信小程序的点餐管理系统毕业设计(源码讲解)

    作者简介:Java.spring.安卓Android.ssm框架.前端.后端开发多年,做过高程,项目经理,架构师 主要内容:Java项目开发.毕业设计开发.技术分享 怎么做基于安卓android和微信 ...

  3. android小闹钟程序,Android实现闹钟小程序.pdf

    Android实实现现闹闹钟钟小小程程序序 这篇文章主要为大家详细介绍了Android实现闹钟小程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 最近写了 闹钟的程序,看到SharedPrefe ...

  4. Android扩展类方法,Android 扩展 uni小程序SDK 原生能力

    Android 扩展 uni小程序SDK 原生能力 概述 本文档主要介绍如何扩展 uni小程序SDK 原生能力. 什么是扩展原生能力? 扩展原生能力指的是将您原生开发的功能通过一定规范暴露给 uni小 ...

  5. Android 仿微信小程序开屏页加载loading

    Android 仿微信小程序开屏页加载loading 废话不多说,先上效果图~ 首先就是底层有一个灰色的圆,然后按照圆形的轨迹进行绘制. 啊~说那么多也没用,还是直接上代码吧,哈哈哈哈 绘制底部圆形及 ...

  6. android 分享小程序到微信,Android 分享微信小程序之图片优化

    小菜上周接入了微信分享小程序的入口,基本功能实现都没问题,有需要的朋友可以了解一下 Android 分享微信小程序失败二三事,虽然功能都正常,但整体测试发现图片展示效果不佳.于是小菜整理了一个简单的小 ...

  7. 微信小程序记事本+后台管理系统

    <微信小程序记事本+后台管理系统>该项目含有源码.论文等资料.配套开发软件.软件安装教程.项目发布教程等 本系统包含微信小程序做的记事本前台和Java做的后台管理系统: 微信小程序--记事 ...

  8. 【毕业设计】基于微信小程序的备忘录记事助手

    文章目录 1 前言 2 简介 3 部分实现步骤与代码 3.1 对象方法属性 3.2 箭头函数(Arrow Function) 3.3 日历 4 最后 1 前言 Hi,大家好,学长今天向大家介绍 一个小 ...

  9. 智慧新零售收银系统包含pc源码安卓小程序进销存等等功能

    智慧新零售收银系统包含pc源码安卓小程序进销存等等功能这里写自定义目录标题 欢迎使用智慧新零售收银系统 欢迎使用智慧新零售收银系统 零售开发语言有:php.HTML5.Java 安卓端收银.助手:原生 ...

最新文章

  1. 下列有关python语言的说法正确的是-关于 Python 语言的注释,以下选项中描述正确的是( )...
  2. oracle实例无法启动也无法关闭
  3. 实验一HSRP与STP结合
  4. dcdc模块降额设计_模块电源应用设计的可靠性和注意事项
  5. 第四届AutoDL挑战赛——AutoSpeech2019正式开赛
  6. pheonix从入门到进阶
  7. 淘宝top平台调用接口响应时间优化
  8. 计算机应用基础模拟三答案,《计算机应用基础》模拟试卷三答案
  9. ggplot2中显示坐标轴_R可视化08|ggplot2图层标度图层(scale layer)图例篇
  10. 计算机软考有学历限制吗,软考中级职称申请积分还需要学历吗?
  11. spring和mybatis结合做简单的增删查改系统_springbootamp;amp;vue简单的景点信息管理系统...
  12. java中介者模式例子_Java中介者模式(Mediator Pattern)
  13. 深入浅出 - 公钥、私钥和数字签名最通俗的理解
  14. Node.js 修复4个漏洞
  15. python绝对值编程_如何在python中取绝对值
  16. 中国矿业大学计算机学院推免,j机电学院2008届毕业生推免工作顺利完成
  17. php asic,ASIC和FPGA的优势与劣势
  18. 清华大学计算机科学与技术系黄必胜,都来看看,我们广西优秀学子在清华大学都读什么专业(2012年)...
  19. iOS MVC设计模式
  20. 华为交换机-不同Vlan如何通信

热门文章

  1. 如何查看ubuntu的内核版本和发行版本号?
  2. CSS面试题整理汇总
  3. redis系列七LUR清除算法
  4. 解决M1芯片mac安装AU( Audition2020)AU2020已适配M1芯片,M1处理器安装AU教程方案
  5. 目前主流服务器厂商有哪些?都有什么型号
  6. Centos7开机自启动手册
  7. 系统迁移里踩过的一点小坑
  8. 【python】Flask之路由
  9. forwardRef的使用
  10. CFileDialog的使用(MFC-C++)