我们知道在android系统中自带的控件也有不少,大部分控件的我们其实可以深度设计
扩展,经过我们精心设计出来的控件,那就是自定义控件了。就像做其他应用程序一样,我们日积月累做的时间长了,为了方便使用我们可以自定义一些自己UI或
者功能型的控件。根据不同的需要定制不同的控件类型,那么简单说一下我怎么来设计这个理财软件的列表UI,其实我就想方便的进行统计和查阅,普通的单行列
表已经满足不了我的需求,我需要的是分级的列表:
父级下面还还有自己的列表,可以伸展、收缩、效果很赞很整!!喜欢的顶起走。。。
我简单的设计了几个图和背景来暂时一下这个分级列表。
下面就是具体的UI设计了,因为是在自带的控件上拓展的,那就重点说一下ExpandableListView这个控件。它的原始模样是这样的:
listcost.xml
具体的UI设计大图及代码:
xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=""
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" android:background="@drawable/licai_bd" android:weightSum="1">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:text=""
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/btn_browser"
android:id="@+id/bt_goback">Button>
<TextView
android:layout_width="wrap_content"
android:layout_marginLeft="3px"
android:textColor="@color/clanse"
android:text="TextView"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/tv_aboutthismoth">
TextView>
LinearLayout>
<ExpandableListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
android:id="@+id/listmonthcostid"
>
ExpandableListView>
LinearLayout>
自定义控件UI设计,首先做一下一级栏目的效果及代码:
lc_listview.xml
xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=""
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/listview_bg">
<TextView
android:layout_width="match_parent"
android:id="@+id/tv_fristtitel"
android:layout_height="wrap_content"
android:text="绑定数据"
android:layout_gravity="center"
android:textSize="16dp"
android:layout_margin="8dp"
android:textColor="@color/clanse2"
>
TextView>
LinearLayout>
自定义控件子级列表的代码及设计图:
lc_listchild.xml
xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android=""
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/listchild_bg" android:gravity="top">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:orientation="vertical" android:id="@+id/linearLayout1">
>
<ImageView
android:layout_width="wrap_content"
android:src="@drawable/xgg"
android:layout_height="wrap_content"
android:id="@+id/imageView1"
android:layout_alignTop="@+id/linearLayout1"
android:layout_alignParentLeft="true">ImageView>
LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="60dp"
android:orientation="vertical" android:id="@+id/linearLayout2">
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/clanse2"
android:text="绑定数据"
android:textSize="16dp" android:id="@+id/txt_fristtext">
TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/clanse"
android:text="绑定数据"
android:textSize="14dp" android:id="@+id/txt_txetinfos">
TextView>
LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:id="@+id/linearLayout3"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_marginRight="23dp">
<ImageView
android:layout_width="wrap_content"
android:src="@drawable/rmb_bg"
android:layout_height="wrap_content"
android:id="@+id/imageView2">
ImageView>
<TextView android:text="TextView"
android:layout_marginLeft="5dp"
android:textColor="@color/clanse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/txt_rmb">
TextView>
LinearLayout>
RelativeLayout>
好了,UI全部写好了,大家可以意淫一下我们的效果图,嘿嘿。我感觉如果出来的效果会很整!!!接下来我们要写自定义控件的代码了,首先我们要写一个类;
类名自定义,不过一定要继承BaseExpandableListAdapter这个控件的基类。因为我们相当于重构。所以引用它原来的接口来直接
写方法了。我们要知道几个点首先我们模仿的是一个分级的菜单列表,那么就有一级和二级,之所以我们之前用
BaseExpandableListAdapter这个类得图形是因为它本就具有这样的造型,只不过我们把他里面的核心元素替换,我说的不专业,但是比
较通俗易懂,下面具体看代码,我们定义一下基本的属性;看看哪些是必备的。
先从我们设计的主页面开始listcost.xml对应listcost类:
final static String F_ListInfo= "fristlistinfo";
final static String C_ListInfo = "childlistinfo";
final static String RmbInfo = "rmbinfo";
SqliteCommen sqlc;//数据库 listchidinfo mylistinfo;//自定义控件类申明
接下来看看 listchidinfo 是怎么写的 :
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
public class listchidinfo extends BaseExpandableListAdapter {
private Context ct_fristinfo;
List<String> frist_titel =new ArrayList<String>();
List<List<Map<String,String>>> list_child = new ArrayList<List<Map<String,String>>>();
///构造函数初始化内容
public listchidinfo(Context context,List<String> a_frist_titel,List<List<Map<String, String>>> a_listchild)
{
this.ct_fristinfo=context;
this.frist_titel = a_frist_titel;
this.list_child = a_listchild;
}
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return list_child.get(groupPosition).get(childPosition).get(listcost.F_ListInfo).toString();
}
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = convertView;
if(view == null){
LayoutInflater inflater = (LayoutInflater)ct_fristinfo.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.lc_listchild, null);
}
final TextView tetfristext = (TextView) view.findViewById(R.id.txt_fristtext);
tetfristext.setText(list_child.get(groupPosition).get(childPosition).get(listcost.F_ListInfo).toString());
final TextView txttxetinfos = (TextView) view.findViewById(R.id.txt_txetinfos);
txttxetinfos.setText(list_child.get(groupPosition).get(childPosition).get(listcost.C_ListInfo).toString());
final TextView txtrmb = (TextView) view.findViewById(R.id.txt_rmb);
txtrmb.setText(list_child.get(groupPosition).get(childPosition).get(listcost.RmbInfo).toString());
return view;
}
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return list_child.get(groupPosition).size();
}
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return frist_titel.get(groupPosition).toString();
}
public int getGroupCount() {
// TODO Auto-generated method stub
return frist_titel.size();
}
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
public View getGroupView(int groupPosition, boolean i***panded,
View convertView, ViewGroup parent) {
View view = convertView;
//将原来的样式替换新样式
if(view == null){
LayoutInflater inflater_new = (LayoutInflater)
ct_fristinfo.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater_new.inflate( R.layout.lc_listview , null);
}
TextView text_titel = (TextView) view.findViewById(R.id.tv_fristtitel);
text_titel.setText(getGroup(groupPosition).toString());
return view;
}
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return false;
}
}
里面重要的就是将新样式R.layout.lc_listview替换原来的样式,并进行新的控件R.ID的赋值。将新的控件的方法也重新绑定上。通过做这个实例可以衍生到其它控件也可以采用这样的方法进行扩展自定义控件。只要自己想得到,那就有百变的造型UI,不是么?今天换一套明天换一套······
然后接下来就是UI里面的数据绑定和书写了,下面是从之的数据表添加来的数据,需要将数据按照月份来绑定,首先弄了2个功能:
1,上个月的开资明细列表情况
2,本月的开资明细列表情况
然后两月的总开资进行对比,嗯,这个就比较人性话了,目前我想到的功能就只有这么方便,这么多,太复杂了我自己不好用,其它人不好用,不过肯定有
一些小毛病的,那是软件版本2.0的事,以后肯定会跟大家说怎么做版本2.0的问题的,任何一款应用软件都会遇到2.0问题···到时候说个详细吧,现在
就不批跨了!
listcost.java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.format.Time;
import android.view.Window;
import android.widget.ExpandableListView;
import android.widget.TextView;
public class listcost extends Activity {
//数据库访问基类
SqliteCommen sqlc;
final static String F_ListInfo= "fristlistinfo";
final static String C_ListInfo = "childlistinfo";
final static String RmbInfo = "rmbinfo";
private int lastmonthspend;
private int thismonthspend;
private String str_lastmonthcount;
private String str_thismonthcount;
listchidinfo mylistinfo ;
ExpandableListView listmonthcost ;
List<String> a_frist_titel = new ArrayList<String>();
List<List<Map<String, String>>> a_listchild = new ArrayList<List<Map<String, String>>>();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//窗体状态设置-设置为无标题栏状态【全屏】
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.listcost);
//自定义控件
listmonthcost = (ExpandableListView)findViewById(R.id.listmonthcostid);
sqlc = new SqliteCommen(this);
SQLiteDatabase db = sqlc.getReadableDatabase();
TextView tv_Allspend = (TextView)findViewById(R.id.tv_aboutthismoth);
final String[] AllFeild =
{
PublicDataCost.ID,
PublicDataCost.Field_1_1,
PublicDataCost.Field_1_2,
PublicDataCost.Field_1_3,
PublicDataCost.Field_1_4,
PublicDataCost.Field_1_5,
PublicDataCost.Field_1_6
};
Time t = new Time();
t.setToNow();
int nowmonth = t.month + 1;
String lastmonth_datetime = t.year +"年" +t.month+ "月";
String thismonth_datetime = t.year +"年" +nowmonth+ "月";
Cursor c_lastmonth = db.query(PublicDataCost.Tb_Name_1 , AllFeild, "DateTimes like '%"+lastmonth_datetime+"%'"
, null, null, null, null);
c_lastmonth.moveToFirst();
List<Map<String, String>> lastmonthlist = new ArrayList<Map<String, String>>();
if(c_lastmonth.getCount()>0)
{
for(int i=0; i<c_lastmonth.getCount() ; i++)
{
lastmonthlist.add(new HashMap<String, String>());
lastmonthlist.get(i).put(F_ListInfo, c_lastmonth.getString(6).toString());
int fan = Integer.parseInt(c_lastmonth.getString(1))
+Integer.parseInt(c_lastmonth.getString(2))+Integer.parseInt(c_lastmonth.getString(3));
lastmonthlist.get(i).put(C_ListInfo, "饭:"+fan +" 购:"+c_lastmonth.getString(4)+ "日:"+c_lastmonth.getString(5));
int lastcost = Integer.parseInt(c_lastmonth.getString(1))
+Integer.parseInt(c_lastmonth.getString(2))+Integer.parseInt(c_lastmonth.getString(3))
+Integer.parseInt(c_lastmonth.getString(4))+Integer.parseInt(c_lastmonth.getString(5));
lastmonthlist.get(i).put(RmbInfo,"¥"+lastcost);
lastmonthspend+=lastcost;
str_lastmonthcount = "¥"+lastmonthspend;
c_lastmonth.moveToNext();
}
}
else
{
lastmonthlist.add(new HashMap<String, String>());
lastmonthlist.get(0).put(F_ListInfo, lastmonth_datetime+"暂无理财");
lastmonthlist.get(0).put(C_ListInfo, "暂无理财信息!");
lastmonthlist.get(0).put(RmbInfo, "¥0.00");
str_lastmonthcount = "¥0.00";
}
a_frist_titel.add("上月理财 总开销:" + str_lastmonthcount);
c_lastmonth.close();
Cursor c = db.query(PublicDataCost.Tb_Name_1 , AllFeild, "DateTimes like '%"+thismonth_datetime+"%'"
, null, null, null, null);
c.moveToFirst();
List<Map<String, String>> childlist = new ArrayList<Map<String,String>>(c.getCount());
for(int i=0; i<c.getCount() ; i++)
{
childlist.add(new HashMap<String, String>());
childlist.get(i).put(F_ListInfo, c.getString(6).toString());
int fan = Integer.parseInt(c.getString(1))+Integer.parseInt(c.getString(2))+Integer.parseInt(c.getString(3));
childlist.get(i).put(C_ListInfo, "饭:"+fan +" 购:"+c.getString(4)+ "日:"+c.getString(5));
int lastcost = Integer.parseInt(c.getString(1))+Integer.parseInt(c.getString(2))
+Integer.parseInt(c.getString(3))+Integer.parseInt(c.getString(4))+Integer.parseInt(c.getString(5));
childlist.get(i).put(RmbInfo,"¥"+lastcost);
thismonthspend+=lastcost;
str_thismonthcount = "¥"+thismonthspend;
c.moveToNext();
}
c.close();
a_frist_titel.add("本月理财 总开销:" + str_thismonthcount);
db.close();
a_listchild.add(lastmonthlist);
a_listchild.add(childlist);
mylistinfo = new listchidinfo(listcost.this, a_frist_titel , a_listchild);
//载入自定义控件
listmonthcost.setAdapter(mylistinfo);
// 去掉系统自带的按钮分隔线
listmonthcost.setGroupIndicator(null);
listmonthcost.setDivider(null);
// 展开所有二级列表
int groupCount = mylistinfo.getGroupCount();
for (int i = 0; i < groupCount; i++) {
listmonthcost.expandGroup(i);
}
tv_Allspend.setText("您本月总开资:"+ str_thismonthcount);
}
}
好了好了,代码写得很整了,不知道效果整不整。
先跑一跑吧!!!
看图:
这个是收起来的效果,下面看看展开的效果整不整?
如果多录几条数据进去可以上下拉动的,效果也是一样的···
下一次发文章,我就发一下关于android图像处理的一些东西,我个人觉得比较犀利,以前我就做sl游戏开发,还有flax游戏也做过,但是这个
图形的差别还是很大的,我预想的做法是做柱状图控件那种。。。再看吧,希望能和各位android开发爱好者一起学习心得知识。
紫秀随身记
紫秀随身记是一款专门为没有理财习惯和的人定制的理财软件和一款随身记事的一款日常实用的免费软件,它具有一键理财,理财统计,写日志,等记账记事的功能。它还有非常清新的界面和字体显示,陪伴您记录每一天的点点滴滴。
下载地址: