日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android 多级树形菜单

發(fā)布時(shí)間:2025/3/17 Android 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 多级树形菜单 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在Android里要實(shí)現(xiàn)樹(shù)形菜單,都是用ExpandableList(也有高手自己繼承ListView或者LinearLayout來(lái)做),但是ExpandableList一般只能實(shí)現(xiàn)2級(jí)樹(shù)形菜單......本文也依然使用ExpandableList,但是要實(shí)現(xiàn)的是3級(jí)樹(shù)形菜單。本文程序運(yùn)行效果圖:

當(dāng)用BaseExpandableListAdapter來(lái)實(shí)現(xiàn)二級(jí)樹(shù)形菜單時(shí),父項(xiàng)(getGroupView())和子項(xiàng)(getChildView())都是使用TextView。當(dāng)要實(shí)現(xiàn)三級(jí)樹(shù)形菜單時(shí),子項(xiàng)(getChildView())就必須使用ExpandableList了.......另外還要定義結(jié)構(gòu)體來(lái)方便調(diào)用三級(jí)樹(shù)形的數(shù)據(jù),二級(jí)樹(shù)形菜單可以用如下:

?

  • static?public?class?TreeNode{??
  • ????Object?parent;??
  • ????List<Object>?childs=new?ArrayList<Object>();??
  • }??
  • ?

    三級(jí)樹(shù)形菜單可以用如下,子項(xiàng)是二級(jí)樹(shù)形菜單的結(jié)構(gòu)體:

    ?

  • static?public?class?SuperTreeNode?{??
  • ????Object?parent;??
  • ????//二級(jí)樹(shù)形菜單的結(jié)構(gòu)體??
  • ????List<TreeViewAdapter.TreeNode>?childs?=?new?ArrayList<TreeViewAdapter.TreeNode>();??
  • }??
  • ?

    實(shí)現(xiàn)三級(jí)樹(shù)形菜單有兩點(diǎn)要注意的:

    1、第二級(jí)也是個(gè)樹(shù)形菜單,因此必須在第二級(jí)項(xiàng)目展開(kāi)/回收時(shí)設(shè)置足夠的空間來(lái)完全顯示二級(jí)樹(shù)形菜單;

    2、在實(shí)現(xiàn)三級(jí)樹(shù)形菜單時(shí),發(fā)現(xiàn)菜單的方法都是用不了(如OnChildClickListener、OnGroupClickListener等),因此要獲得選中的數(shù)據(jù)就必須在外部定義好回調(diào)函數(shù),然后在第二級(jí)生成二級(jí)樹(shù)形菜單時(shí)回調(diào)這個(gè)外部函數(shù)。

    PS:本文在解決No.2關(guān)鍵點(diǎn)的時(shí)候,只能取得第三級(jí)選中的序號(hào).....而第一,第二級(jí)依然無(wú)法獲取其序號(hào)。

    main.xml源碼如下:

    ?

  • <?xml?version="1.0"?encoding="utf-8"?>??
  • <LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"??
  • ????android:orientation="vertical"?android:layout_width="fill_parent"??
  • ????android:layout_height="fill_parent">??
  • ????<LinearLayout?android:id="@+id/LinearLayout01"??
  • ????????android:layout_width="wrap_content"?android:layout_height="wrap_content">??
  • ????????<Button?android:layout_height="wrap_content"?android:text="兩層結(jié)構(gòu)"??
  • ????????????android:layout_width="160dip"?android:id="@+id/btnNormal"></Button>??
  • ????????<Button?android:layout_height="wrap_content"?android:text="三層結(jié)構(gòu)"??
  • ????????????android:layout_width="160dip"?android:id="@+id/btnSuper"></Button>??
  • ????</LinearLayout>??
  • ????<ExpandableListView?android:id="@+id/ExpandableListView01"??
  • ????????android:layout_width="fill_parent"?android:layout_height="fill_parent"></ExpandableListView>??
  • </LinearLayout>??
  • ?

    testExpandableList.java是主類,調(diào)用其他工具類,源碼如下:

    ?

  • package?com.testExpandableList;??
  • ??
  • ??
  • import?java.util.List;??
  • import?android.app.Activity;??
  • import?android.os.Bundle;??
  • import?android.util.Log;??
  • import?android.view.View;??
  • import?android.widget.Button;??
  • import?android.widget.ExpandableListView;??
  • import?android.widget.ExpandableListView.OnChildClickListener;??
  • import?android.widget.Toast;??
  • ??
  • public?class?testExpandableList?extends?Activity?{??
  • ????/**?Called?when?the?activity?is?first?created.?*/??
  • ????ExpandableListView?expandableList;??
  • ????TreeViewAdapter?adapter;??
  • ????SuperTreeViewAdapter?superAdapter;??
  • ????Button?btnNormal,btnSuper;??
  • ????//?Sample?data?set.??children[i]?contains?the?children?(String[])?for?groups[i].??
  • ????public?String[]?groups?=?{?"xxxx好友",?"xxxx同學(xué)",?"xxxxx女人"};??
  • ????public?String[][]??child=?{??
  • ????????????{?"A君",?"B君",?"C君",?"D君"?},??
  • ????????????{?"同學(xué)甲",?"同學(xué)乙",?"同學(xué)丙"},??
  • ????????????{?"御姐",?"蘿莉"?}??
  • ????};??
  • ??????
  • ????public?String[]?parent?=?{?"xxxx好友",?"xxxx同學(xué)"};??
  • ????public?String[][][]??child_grandson=?{??
  • ????????????{{"A君"},??
  • ????????????????{"AA","AAA"}},??
  • ????????????{{"B君"},??
  • ????????????????{"BBB","BBBB","BBBBB"}},??
  • ????????????{{"C君"},??
  • ????????????????{"CCC","CCCC"}},??
  • ????????????{{"D君"},??
  • ????????????????{"DDD","DDDD","DDDDD"}},??
  • ????};??
  • ??????
  • ????@Override??
  • ????public?void?onCreate(Bundle?savedInstanceState)?{??
  • ????????super.onCreate(savedInstanceState);??
  • ????????setContentView(R.layout.main);??
  • ????????this.setTitle("ExpandableListView練習(xí)----hellogv");??
  • ????????btnNormal=(Button)this.findViewById(R.id.btnNormal);??
  • ????????btnNormal.setOnClickListener(new?ClickEvent());??
  • ????????btnSuper=(Button)this.findViewById(R.id.btnSuper);??
  • ????????btnSuper.setOnClickListener(new?ClickEvent());??
  • ????????adapter=new?TreeViewAdapter(this,TreeViewAdapter.PaddingLeft>>1);??
  • ????????superAdapter=new?SuperTreeViewAdapter(this,stvClickEvent);??
  • ????????expandableList=(ExpandableListView)?testExpandableList.this.findViewById(R.id.ExpandableListView01);??
  • ????}??
  • ??????
  • ????class?ClickEvent?implements?View.OnClickListener{??
  • ??
  • ????????@Override??
  • ????????public?void?onClick(View?v)?{??
  • ????????????adapter.RemoveAll();??
  • ????????????adapter.notifyDataSetChanged();??
  • ????????????superAdapter.RemoveAll();??
  • ????????????superAdapter.notifyDataSetChanged();??
  • ??????????????
  • ????????????if(v==btnNormal)??
  • ????????????{??
  • ????????????????List<TreeViewAdapter.TreeNode>?treeNode?=?adapter.GetTreeNode();??
  • ????????????????for(int?i=0;i<groups.length;i++)??
  • ????????????????{??
  • ????????????????????TreeViewAdapter.TreeNode?node=new?TreeViewAdapter.TreeNode();??
  • ????????????????????node.parent=groups[i];??
  • ????????????????????for(int?ii=0;ii<child[i].length;ii++)??
  • ????????????????????{??
  • ????????????????????????node.childs.add(child[i][ii]);??
  • ????????????????????}??
  • ????????????????????treeNode.add(node);??
  • ????????????????}??
  • ??????????????????
  • ????????????????adapter.UpdateTreeNode(treeNode);???????
  • ????????????????expandableList.setAdapter(adapter);??
  • ????????????????expandableList.setOnChildClickListener(new?OnChildClickListener(){??
  • ??
  • ????????????????????@Override??
  • ????????????????????public?boolean?onChildClick(ExpandableListView?arg0,?View?arg1,??
  • ????????????????????????????int?parent,?int?children,?long?arg4)?{??
  • ??????????????????????????
  • ????????????????????????String?str="parent?id:"+String.valueOf(parent)+",children?id:"+String.valueOf(children);??
  • ????????????????????????Toast.makeText(testExpandableList.this,?str,?300).show();??
  • ????????????????????????return?false;??
  • ????????????????????}??
  • ????????????????});??
  • ????????????}??
  • ????????????else?if(v==btnSuper){??
  • ????????????????List<SuperTreeViewAdapter.SuperTreeNode>?superTreeNode?=?superAdapter.GetTreeNode();??
  • ????????????????for(int?i=0;i<parent.length;i++)//第一層??
  • ????????????????{??
  • ????????????????????SuperTreeViewAdapter.SuperTreeNode?superNode=new?SuperTreeViewAdapter.SuperTreeNode();??
  • ????????????????????superNode.parent=parent[i];??
  • ??????????????????????
  • ????????????????????//第二層??
  • ????????????????????for(int?ii=0;ii<child_grandson.length;ii++)??
  • ????????????????????{??
  • ????????????????????????TreeViewAdapter.TreeNode?node=new?TreeViewAdapter.TreeNode();??
  • ????????????????????????node.parent=child_grandson[ii][0][0];//第二級(jí)菜單的標(biāo)題??
  • ??????????????????????????
  • ????????????????????????for(int?iii=0;iii<child_grandson[ii][1].length;iii++)//第三級(jí)菜單??
  • ????????????????????????{??
  • ????????????????????????????node.childs.add(child_grandson[ii][1][iii]);??
  • ????????????????????????}??
  • ????????????????????????superNode.childs.add(node);??
  • ????????????????????}??
  • ????????????????????superTreeNode.add(superNode);??
  • ??????????????????????
  • ????????????????}??
  • ????????????????superAdapter.UpdateTreeNode(superTreeNode);??
  • ????????????????expandableList.setAdapter(superAdapter);??
  • ????????????}??
  • ????????}??
  • ????}??
  • ??
  • ????/**?
  • ?????*?三級(jí)樹(shù)形菜單的事件不再可用,本函數(shù)由三級(jí)樹(shù)形菜單的子項(xiàng)(二級(jí)菜單)進(jìn)行回調(diào)?
  • ?????*/??
  • ????OnChildClickListener?stvClickEvent=new?OnChildClickListener(){??
  • ??
  • ????????@Override??
  • ????????public?boolean?onChildClick(ExpandableListView?parent,??
  • ????????????????View?v,?int?groupPosition,?int?childPosition,??
  • ????????????????long?id)?{??
  • ????????????String?str="parent?id:"+String.valueOf(groupPosition)+",children?id:"+String.valueOf(childPosition);??
  • ????????????Toast.makeText(testExpandableList.this,?str,?300).show();??
  • ??????????????
  • ????????????return?false;??
  • ????????}??
  • ??????????
  • ????};??
  • }??
  • ?

    TreeViewAdapter.java是實(shí)現(xiàn)二級(jí)樹(shù)形菜單的工具類,源碼如下:

    ?

  • package?com.testExpandableList;??
  • ??
  • import?java.util.ArrayList;??
  • import?java.util.List;??
  • import?android.content.Context;??
  • import?android.util.Log;??
  • import?android.view.Gravity;??
  • import?android.view.View;??
  • import?android.view.ViewGroup;??
  • import?android.widget.AbsListView;??
  • import?android.widget.BaseExpandableListAdapter;??
  • import?android.widget.TextView;??
  • ??
  • ??
  • public?class?TreeViewAdapter?extends?BaseExpandableListAdapter{??
  • ????public?static?final?int?ItemHeight=48;//每項(xiàng)的高度??
  • ????public?static?final?int?PaddingLeft=36;//每項(xiàng)的高度??
  • ????private?int?myPaddingLeft=0;//如果是由SuperTreeView調(diào)用,則作為子項(xiàng)需要往右移??
  • ??
  • ????static?public?class?TreeNode{??
  • ????????Object?parent;??
  • ????????List<Object>?childs=new?ArrayList<Object>();??
  • ????}??
  • ??????
  • ????List<TreeNode>?treeNodes?=?new?ArrayList<TreeNode>();??
  • ????Context?parentContext;??
  • ??????
  • ????public?TreeViewAdapter(Context?view,int?myPaddingLeft)??
  • ????{??
  • ????????parentContext=view;??
  • ????????this.myPaddingLeft=myPaddingLeft;??
  • ????}??
  • ??????
  • ????public?List<TreeNode>?GetTreeNode()??
  • ????{??
  • ????????return?treeNodes;??
  • ????}??
  • ??????
  • ????public?void?UpdateTreeNode(List<TreeNode>?nodes)??
  • ????{??
  • ????????treeNodes=nodes;??
  • ????}??
  • ??????
  • ????public?void?RemoveAll()??
  • ????{??
  • ????????treeNodes.clear();??
  • ????}??
  • ??????
  • ????public?Object?getChild(int?groupPosition,?int?childPosition)?{??
  • ????????return?treeNodes.get(groupPosition).childs.get(childPosition);??
  • ????}??
  • ??
  • ????public?int?getChildrenCount(int?groupPosition)?{??
  • ????????return?treeNodes.get(groupPosition).childs.size();??
  • ????}??
  • ??
  • ????static?public?TextView?getTextView(Context?context)?{??
  • ????????AbsListView.LayoutParams?lp?=?new?AbsListView.LayoutParams(??
  • ????????????????ViewGroup.LayoutParams.FILL_PARENT,?ItemHeight);??
  • ??
  • ????????TextView?textView?=?new?TextView(context);??
  • ????????textView.setLayoutParams(lp);??
  • ????????textView.setGravity(Gravity.CENTER_VERTICAL?|?Gravity.LEFT);??
  • ????????return?textView;??
  • ????}??
  • ??
  • ????public?View?getChildView(int?groupPosition,?int?childPosition,??
  • ????????????boolean?isLastChild,?View?convertView,?ViewGroup?parent)?{??
  • ????????TextView?textView?=?getTextView(this.parentContext);??
  • ????????textView.setText(getChild(groupPosition,?childPosition).toString());??
  • ????????textView.setPadding(myPaddingLeft+PaddingLeft,?0,?0,?0);??
  • ????????return?textView;??
  • ????}??
  • ??
  • ????public?View?getGroupView(int?groupPosition,?boolean?isExpanded,??
  • ????????????View?convertView,?ViewGroup?parent)?{??
  • ????????TextView?textView?=?getTextView(this.parentContext);??
  • ????????textView.setText(getGroup(groupPosition).toString());??
  • ????????textView.setPadding(myPaddingLeft+(PaddingLeft>>1),?0,?0,?0);??
  • ????????return?textView;??
  • ????}??
  • ??
  • ????public?long?getChildId(int?groupPosition,?int?childPosition)?{??
  • ????????return?childPosition;??
  • ????}??
  • ??
  • ????public?Object?getGroup(int?groupPosition)?{??
  • ????????return?treeNodes.get(groupPosition).parent;??
  • ????}??
  • ??
  • ????public?int?getGroupCount()?{??
  • ????????return?treeNodes.size();??
  • ????}??
  • ??
  • ????public?long?getGroupId(int?groupPosition)?{??
  • ????????return?groupPosition;??
  • ????}??
  • ??
  • ????public?boolean?isChildSelectable(int?groupPosition,?int?childPosition)?{??
  • ????????return?true;??
  • ????}??
  • ??
  • ????public?boolean?hasStableIds()?{??
  • ????????return?true;??
  • ????}??
  • }??
  • ?

    SuperTreeViewAdapter.java是實(shí)現(xiàn)三級(jí)樹(shù)形菜單的工具類,會(huì)用到TreeViewAdapter.java,源碼如下:

    ?

  • package?com.testExpandableList;??
  • ??
  • import?java.util.ArrayList;??
  • import?java.util.List;??
  • import?com.testExpandableList.TreeViewAdapter.TreeNode;??
  • import?android.content.Context;??
  • import?android.view.View;??
  • import?android.view.ViewGroup;??
  • import?android.widget.AbsListView;??
  • import?android.widget.BaseExpandableListAdapter;??
  • import?android.widget.ExpandableListView;??
  • import?android.widget.ExpandableListView.OnChildClickListener;??
  • import?android.widget.ExpandableListView.OnGroupCollapseListener;??
  • import?android.widget.ExpandableListView.OnGroupExpandListener;??
  • import?android.widget.TextView;??
  • ??
  • public?class?SuperTreeViewAdapter?extends?BaseExpandableListAdapter?{??
  • ??
  • ????static?public?class?SuperTreeNode?{??
  • ????????Object?parent;??
  • ????????//二級(jí)樹(shù)形菜單的結(jié)構(gòu)體??
  • ????????List<TreeViewAdapter.TreeNode>?childs?=?new?ArrayList<TreeViewAdapter.TreeNode>();??
  • ????}??
  • ??
  • ????private?List<SuperTreeNode>?superTreeNodes?=?new?ArrayList<SuperTreeNode>();??
  • ????private?Context?parentContext;??
  • ????private?OnChildClickListener?stvClickEvent;//外部回調(diào)函數(shù)??
  • ??????
  • ????public?SuperTreeViewAdapter(Context?view,OnChildClickListener?stvClickEvent)?{??
  • ????????parentContext?=?view;??
  • ????????this.stvClickEvent=stvClickEvent;??
  • ????}??
  • ??
  • ????public?List<SuperTreeNode>?GetTreeNode()?{??
  • ????????return?superTreeNodes;??
  • ????}??
  • ??
  • ????public?void?UpdateTreeNode(List<SuperTreeNode>?node)?{??
  • ????????superTreeNodes?=?node;??
  • ????}??
  • ??????
  • ????public?void?RemoveAll()??
  • ????{??
  • ????????superTreeNodes.clear();??
  • ????}??
  • ??????
  • ????public?Object?getChild(int?groupPosition,?int?childPosition)?{??
  • ????????return?superTreeNodes.get(groupPosition).childs.get(childPosition);??
  • ????}??
  • ??
  • ????public?int?getChildrenCount(int?groupPosition)?{??
  • ????????return?superTreeNodes.get(groupPosition).childs.size();??
  • ????}??
  • ??
  • ????public?ExpandableListView?getExpandableListView()?{??
  • ????????AbsListView.LayoutParams?lp?=?new?AbsListView.LayoutParams(??
  • ????????????????ViewGroup.LayoutParams.FILL_PARENT,?TreeViewAdapter.ItemHeight);??
  • ????????ExpandableListView?superTreeView?=?new?ExpandableListView(parentContext);??
  • ????????superTreeView.setLayoutParams(lp);??
  • ????????return?superTreeView;??
  • ????}??
  • ??
  • ????/**?
  • ?????*?三層樹(shù)結(jié)構(gòu)中的第二層是一個(gè)ExpandableListView?
  • ?????*/???
  • ????public?View?getChildView(int?groupPosition,?int?childPosition,??
  • ????????????boolean?isLastChild,?View?convertView,?ViewGroup?parent)?{??
  • ????????//?是???
  • ????????final?ExpandableListView?treeView?=?getExpandableListView();??
  • ????????final?TreeViewAdapter?treeViewAdapter?=?new?TreeViewAdapter(this.parentContext,0);??
  • ????????List<TreeNode>?tmp?=?treeViewAdapter.GetTreeNode();//臨時(shí)變量取得TreeViewAdapter的TreeNode集合,可為空??
  • ????????final?TreeNode?treeNode=(TreeNode)?getChild(groupPosition,?childPosition);??
  • ????????tmp.add(treeNode);??
  • ????????treeViewAdapter.UpdateTreeNode(tmp);??
  • ????????treeView.setAdapter(treeViewAdapter);??
  • ??????????
  • ????????//關(guān)鍵點(diǎn):取得選中的二級(jí)樹(shù)形菜單的父子節(jié)點(diǎn),結(jié)果返回給外部回調(diào)函數(shù)??
  • ????????treeView.setOnChildClickListener(this.stvClickEvent);??
  • ??????????
  • ????????/**?
  • ?????????*?關(guān)鍵點(diǎn):第二級(jí)菜單展開(kāi)時(shí)通過(guò)取得節(jié)點(diǎn)數(shù)來(lái)設(shè)置第三級(jí)菜單的大小?
  • ?????????*/??
  • ????????treeView.setOnGroupExpandListener(new?OnGroupExpandListener()?{??
  • ????????????@Override??
  • ????????????public?void?onGroupExpand(int?groupPosition)?{??
  • ??????????????????
  • ????????????????AbsListView.LayoutParams?lp?=?new?AbsListView.LayoutParams(??
  • ????????????????????????ViewGroup.LayoutParams.FILL_PARENT,??
  • ????????????????????????(treeNode.childs.size()+1)*TreeViewAdapter.ItemHeight?+?10);??
  • ????????????????treeView.setLayoutParams(lp);??
  • ????????????}??
  • ????????});??
  • ??????????
  • ????????/**?
  • ?????????*?第二級(jí)菜單回收時(shí)設(shè)置為標(biāo)準(zhǔn)Item大小?
  • ?????????*/??
  • ????????treeView.setOnGroupCollapseListener(new?OnGroupCollapseListener()?{??
  • ????????????@Override??
  • ????????????public?void?onGroupCollapse(int?groupPosition)?{??
  • ??????????????????
  • ????????????????AbsListView.LayoutParams?lp?=?new?AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,??
  • ????????????????????????TreeViewAdapter.ItemHeight);??
  • ????????????????treeView.setLayoutParams(lp);??
  • ????????????}??
  • ????????});??
  • ????????treeView.setPadding(TreeViewAdapter.PaddingLeft,?0,?0,?0);??
  • ????????return?treeView;??
  • ????}??
  • ??
  • ????/**?
  • ?????*?三級(jí)樹(shù)結(jié)構(gòu)中的首層是TextView,用于作為title?
  • ?????*/??
  • ????public?View?getGroupView(int?groupPosition,?boolean?isExpanded,??
  • ????????????View?convertView,?ViewGroup?parent)?{??
  • ????????TextView?textView?=?TreeViewAdapter.getTextView(this.parentContext);??
  • ????????textView.setText(getGroup(groupPosition).toString());??
  • ????????textView.setPadding(TreeViewAdapter.PaddingLeft,?0,?0,?0);??
  • ????????return?textView;??
  • ????}??
  • ??
  • ????public?long?getChildId(int?groupPosition,?int?childPosition)?{??
  • ????????return?childPosition;??
  • ????}??
  • ??
  • ????public?Object?getGroup(int?groupPosition)?{??
  • ????????return?superTreeNodes.get(groupPosition).parent;??
  • ????}??
  • ??
  • ????public?int?getGroupCount()?{??
  • ????????return?superTreeNodes.size();??
  • ????}??
  • ??
  • ????public?long?getGroupId(int?groupPosition)?{??
  • ????????return?groupPosition;??
  • ????}??
  • ??
  • ????public?boolean?isChildSelectable(int?groupPosition,?int?childPosition)?{??
  • ????????return?true;??
  • ????}??
  • ??
  • ????public?boolean?hasStableIds()?{??
  • ????????return?true;??
  • ????}??
  • }??
  • ?

    總結(jié),使用ExpandableList實(shí)現(xiàn)三級(jí)樹(shù)形菜單時(shí)有些bug不好解決,而且定義三維數(shù)組的時(shí)候也要倍加小心......所以盡量把數(shù)據(jù)化簡(jiǎn)來(lái)使用二級(jí)樹(shù)形菜單。

    總結(jié)

    以上是生活随笔為你收集整理的Android 多级树形菜单的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。