android开发实战-记账本APP(一)
<p><span style="font-family: 楷体; font-size: 18px">记账本开发流程:</span></p><p><span style="font-family: 楷体; font-size: 18px">对于一个记账本的初步开发而言,我实现的功能有:</span></p>
<p><span style="font-family: 楷体; font-size: 18px">①实现一个记账本的页面</span></p>
<p><span style="font-family: 楷体; font-size: 18px">②可以添加数据并更新到页面中</span></p>
<p><span style="font-family: 楷体; font-size: 18px">③可以将数据信息以图表的形式展现</span></p>
<p> </p>
<p><span style="font-family: 楷体; font-size: 18px">(一)首先,制作一个记账本的页面。</span></p>
<p><span style="font-family: 楷体; font-size: 18px">①在系统自动创建的content_main.xml文件中添加listview</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">ListView
</span><span style="color: rgba(255, 0, 0, 1)">android:id</span><span style="color: rgba(0, 0, 255, 1)">="@+id/lv_main"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_width</span><span style="color: rgba(0, 0, 255, 1)">="wrap_content"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_height</span><span style="color: rgba(0, 0, 255, 1)">="wrap_content"</span> <span style="color: rgba(0, 0, 255, 1)">/></span></pre>
</div>
<p><span style="font-family: 楷体; font-size: 18px">②创建一个list_item.xml来实现见记账本的页面布局,一共需要三个组件,一个是记账信息,记账时间,记账金额<br></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)"><?</span><span style="color: rgba(255, 0, 255, 1)">xml version="1.0" encoding="utf-8"</span><span style="color: rgba(0, 0, 255, 1)">?></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">RelativeLayout </span><span style="color: rgba(255, 0, 0, 1)">xmlns:android</span><span style="color: rgba(0, 0, 255, 1)">="http://schemas.android.com/apk/res/android"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_width</span><span style="color: rgba(0, 0, 255, 1)">="match_parent"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_height</span><span style="color: rgba(0, 0, 255, 1)">="80dp"</span><span style="color: rgba(255, 0, 0, 1)">
android:orientation</span><span style="color: rgba(0, 0, 255, 1)">="vertical"</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">TextView
</span><span style="color: rgba(255, 0, 0, 1)">android:id</span><span style="color: rgba(0, 0, 255, 1)">="@+id/tv_title"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_width</span><span style="color: rgba(0, 0, 255, 1)">="150dp"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_height</span><span style="color: rgba(0, 0, 255, 1)">="80dp"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_marginLeft</span><span style="color: rgba(0, 0, 255, 1)">="10dp"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_alignParentLeft</span><span style="color: rgba(0, 0, 255, 1)">="true"</span><span style="color: rgba(255, 0, 0, 1)">
android:gravity</span><span style="color: rgba(0, 0, 255, 1)">="center"</span><span style="color: rgba(255, 0, 0, 1)">
android:singleLine</span><span style="color: rgba(0, 0, 255, 1)">="true"</span><span style="color: rgba(255, 0, 0, 1)">
android:textSize</span><span style="color: rgba(0, 0, 255, 1)">="35sp"</span><span style="color: rgba(255, 0, 0, 1)">
android:text</span><span style="color: rgba(0, 0, 255, 1)">="costTitle"</span><span style="color: rgba(255, 0, 0, 1)">
android:ellipsize</span><span style="color: rgba(0, 0, 255, 1)">="marquee"</span> <span style="color: rgba(0, 0, 255, 1)">/></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">TextView
</span><span style="color: rgba(255, 0, 0, 1)">android:id</span><span style="color: rgba(0, 0, 255, 1)">="@+id/tv_date"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_width</span><span style="color: rgba(0, 0, 255, 1)">="wrap_content"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_height</span><span style="color: rgba(0, 0, 255, 1)">="80dp"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_toRightOf</span><span style="color: rgba(0, 0, 255, 1)">="@+id/tv_title"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_marginLeft</span><span style="color: rgba(0, 0, 255, 1)">="15dp"</span><span style="color: rgba(255, 0, 0, 1)">
android:textSize</span><span style="color: rgba(0, 0, 255, 1)">="20sp"</span><span style="color: rgba(255, 0, 0, 1)">
android:gravity</span><span style="color: rgba(0, 0, 255, 1)">="center"</span><span style="color: rgba(255, 0, 0, 1)">
android:text</span><span style="color: rgba(0, 0, 255, 1)">="costDate"</span><span style="color: rgba(0, 0, 255, 1)">/></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">TextView
</span><span style="color: rgba(255, 0, 0, 1)">android:id</span><span style="color: rgba(0, 0, 255, 1)">="@+id/tv_cost"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_width</span><span style="color: rgba(0, 0, 255, 1)">="wrap_content"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_height</span><span style="color: rgba(0, 0, 255, 1)">="80dp"</span><span style="color: rgba(255, 0, 0, 1)">
android:text</span><span style="color: rgba(0, 0, 255, 1)">="30"</span><span style="color: rgba(255, 0, 0, 1)">
android:textSize</span><span style="color: rgba(0, 0, 255, 1)">="30sp"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_marginRight</span><span style="color: rgba(0, 0, 255, 1)">="20dp"</span><span style="color: rgba(255, 0, 0, 1)">
android:layout_alignParentRight</span><span style="color: rgba(0, 0, 255, 1)">="true"</span><span style="color: rgba(255, 0, 0, 1)">
android:gravity</span><span style="color: rgba(0, 0, 255, 1)">="center"</span><span style="color: rgba(0, 0, 255, 1)">/></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">RelativeLayout</span><span style="color: rgba(0, 0, 255, 1)">></span></pre>
</div>
<p><span style="font-family: 楷体; font-size: 18px">页面截图:</span></p>
<p><span style="font-family: 楷体; font-size: 18px"><img src="https://img2018.cnblogs.com/i-beta/1717524/202002/1717524-20200203232716224-613826158.png" alt="" width="611" height="435"></span></p>
<p> </p>
<p> </p>
<p><span style="font-family: 楷体; font-size: 18px"> ③编写适配器并进行测试,因此我们需要建立一个CostListAdapter.java,还需要建立我们的bean对象,因此需要在建立一个CostBean来存储我们的</span></p>
<p><span style="font-family: 楷体; font-size: 18px">记账信息。</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> com.example.xlfbook;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.content.Context;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.view.LayoutInflater;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.view.View;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.view.ViewGroup;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.widget.BaseAdapter;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.widget.TextView;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.util.List;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> CostListAdapter <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> BaseAdapter {
</span><span style="color: rgba(0, 0, 255, 1)">private</span> List<CostBean><span style="color: rgba(0, 0, 0, 1)"> mlist;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> Context mContext;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> LayoutInflater mlayoutInflater;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> CostListAdapter(Context context,List<CostBean><span style="color: rgba(0, 0, 0, 1)"> list){
mContext</span>=<span style="color: rgba(0, 0, 0, 1)">context;
mlist</span>=<span style="color: rgba(0, 0, 0, 1)">list;
mlayoutInflater</span>=<span style="color: rgba(0, 0, 0, 1)">LayoutInflater.from(context);
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getCount() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> mlist.size();
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> Object getItem(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> position) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> mlist.get(position);
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">long</span> getItemId(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> position) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> position;
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> View getView(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(convertView==<span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
viewHolder</span>=<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ViewHolder();
convertView</span>=mlayoutInflater.inflate(R.layout.list_item,<span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">);
viewHolder.mTvCostTitle</span>=<span style="color: rgba(0, 0, 0, 1)">convertView.findViewById(R.id.tv_title);
viewHolder.mTvCostDate</span>=<span style="color: rgba(0, 0, 0, 1)">convertView.findViewById(R.id.tv_date);
viewHolder.mTvCostMoney</span>=<span style="color: rgba(0, 0, 0, 1)">convertView.findViewById(R.id.tv_cost);
convertView.setTag(viewHolder);
}</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
viewHolder</span>=<span style="color: rgba(0, 0, 0, 1)">(ViewHolder) convertView.getTag();
}
CostBean bean</span>=<span style="color: rgba(0, 0, 0, 1)">mlist.get(position);
viewHolder.mTvCostTitle.setText(bean.costTitle);
viewHolder.mTvCostDate.setText(bean.costDate);
viewHolder.mTvCostMoney.setText(bean.costMoney);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> convertView;
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> ViewHolder{
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> TextView mTvCostTitle;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> TextView mTvCostDate;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> TextView mTvCostMoney;
}
}</span></pre>
</div>
<p><span style="font-family: 楷体; font-size: 18px">CostBean,这里implements的意义是为了一会的intent数据传递。</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> com.example.xlfbook;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.io.Serializable;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> CostBean <span style="color: rgba(0, 0, 255, 1)">implements</span><span style="color: rgba(0, 0, 0, 1)"> Serializable {
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String costTitle;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String costDate;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String costMoney;
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String toString() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> "CostBean{" +
"costTitle='" + costTitle + '\'' +
", costDate='" + costDate + '\'' +
", costMoney='" + costMoney + '\'' +
'}'<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getCostDate() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> costDate;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setCostDate(String costDate) {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.costDate =<span style="color: rgba(0, 0, 0, 1)"> costDate;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getCostMoney() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> costMoney;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setCostMoney(String costMoney) {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.costMoney =<span style="color: rgba(0, 0, 0, 1)"> costMoney;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getCostTitle() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> costTitle;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setCostTitle(String costTitle) {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.costTitle =<span style="color: rgba(0, 0, 0, 1)"> costTitle;
}
}</span></pre>
</div>
<p><span style="font-family: 楷体; font-size: 18px">④再然后在主程序中获取ListView并设置adapter,并进行适配器的测试。</span></p>
<p> </p>
<p><span style="font-family: 楷体; font-size: 18px">(二)进行数据库的操作</span></p>
<p><span style="font-family: 楷体; font-size: 18px">①建立数据库实现增/删/查的方法实现。</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> com.example.xlfbook;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.content.ContentValues;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.content.Context;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.database.Cursor;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.database.sqlite.SQLiteDatabase;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.database.sqlite.SQLiteOpenHelper;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> androidx.annotation.Nullable;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> DatabaseHelper <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> SQLiteOpenHelper {
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String COST_TITLE = "cost_title"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String COST_DATE = "cost_date"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String COST_MONEY = "cost_money"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String IMOOC_COST = "imooc_cost"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> DatabaseHelper(@Nullable Context context) {
</span><span style="color: rgba(0, 0, 255, 1)">super</span>(context, "imooc_daily", <span style="color: rgba(0, 0, 255, 1)">null</span>, 1<span style="color: rgba(0, 0, 0, 1)">);
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onCreate(SQLiteDatabase db) {
db.execSQL(</span>"create table if not exists IMOOC_COST("+
"id integer primary key, "+
"cost_title varchar, "+
"cost_date varchar, "+
"cost_money varchar)"<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> insertCost(CostBean costBean)
{
SQLiteDatabase database</span>=<span style="color: rgba(0, 0, 0, 1)">getWritableDatabase();
ContentValues cv</span>=<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ContentValues();
cv.put(COST_TITLE,costBean.costTitle);
cv.put(COST_DATE,costBean.costDate);
cv.put(COST_MONEY,costBean.costMoney);
database.insert(IMOOC_COST,</span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">,cv);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Cursor getAllCostData(){
SQLiteDatabase database</span>=<span style="color: rgba(0, 0, 0, 1)">getWritableDatabase();
</span><span style="color: rgba(0, 0, 255, 1)">return</span> database.query("IMOOC_COST",<span style="color: rgba(0, 0, 255, 1)">null</span>,<span style="color: rgba(0, 0, 255, 1)">null</span>,<span style="color: rgba(0, 0, 255, 1)">null</span>,<span style="color: rgba(0, 0, 255, 1)">null</span>,<span style="color: rgba(0, 0, 255, 1)">null</span>,"COST_DATE "+" ASC"<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> deleteAllData(){
SQLiteDatabase database</span>=<span style="color: rgba(0, 0, 0, 1)">getWritableDatabase();
database.delete(</span>"IMOOC_COST",<span style="color: rgba(0, 0, 255, 1)">null</span>,<span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">);
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> onUpgrade(SQLiteDatabase db, <span style="color: rgba(0, 0, 255, 1)">int</span> oldVersion, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> newVersion) {
}
}</span></pre>
</div>
<p><span style="font-family: 楷体; font-size: 18px">在这里新建了一个“imooc_daily”的数据库和“imooc_cost”表,并对他们以及数据信息(cost_title,cost_date,cost_money)进行了常量定义,以便其他程序的使用,并写了简单的增加、删除和查询数据的功能。</span></p>
<p> </p>
<p><span style="font-family: 楷体; font-size: 18px">今天开发就到这里,明天继续开发实现“添加页面的显示与更新”以及“图表的实现”,最后会发布到github里。</span></p><br><br>
来源:https://www.cnblogs.com/xiaofengzai/p/12258104.html
頁:
[1]