ListView实现漂亮的自定义表格实例

在这里我们要使用Android ListView来实现显示股票行情,效果图如下,红色表示股票价格上涨,绿色表示股票价格下跌。

第一步、定义color.xml如下:

?
1
2
3
4
5
6
7
8
9
xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="color_dark_grey">#808080color>
    <color name="color_black">#000000color>
    <color name="color_green">#00FF00color>
    <color name="color_red">#FF0000color>
    <color name="color_white">#FFFFFFcolor>
resources>

第二步、定义style.xml文件如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
xml version="1.0" encoding="utf-8"?>
<resources>
    
    <style name="list_item_seperator_layout">
        <item name="android:layout_width">fill_parentitem>
        <item name="android:layout_height">1dipitem>
        <item name="android:background">@color/color_dark_greyitem>
    style>
    <style name="list_item_cell_seperator_layout">
        <item name="android:layout_width">1dipitem>
        <item name="android:layout_height">fill_parentitem>
        <item name="android:background">@color/color_dark_greyitem>
    style>
    
resources>

第三步、定义ListHeader的layout文件,stock_list_header.xml如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content">
    <TableLayout 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:stretchColumns="3">
        <TableRow 
            android:id="@+id/stock_list_header_row">
            <View 
                style="@style/list_item_cell_seperator_layout" 
                />
            <TextView 
                android:id="@+id/stock_list_header_code"
                android:text="@string/stock_code" 
                android:layout_width="60dip"
                android:layout_height="wrap_content" 
                android:layout_gravity="center"
                android:padding="2dip" 
                />
            <View 
                style="@style/list_item_cell_seperator_layout" 
                />
            <TextView 
                android:id="@+id/stock_list_header_symbol"
                android:text="@string/stock_symbol" 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" 
                android:layout_gravity="center"
                android:padding="2dip" 
                />
            <View 
                style="@style/list_item_cell_seperator_layout" 
                />
            <TextView 
                android:id="@+id/stock_list_header_last_price"
                android:text="@string/stock_last_price" 
                android:layout_width="60dip"
                android:layout_height="wrap_content" 
                android:layout_gravity="center"
                android:padding="2dip" 
                />
            <View 
                style="@style/list_item_cell_seperator_layout" 
                />
            <TextView 
                android:id="@+id/stock_list_header_price_change"
                android:text="@string/stock_price_change" 
                android:layout_width="50dip"
                android:layout_height="wrap_content" 
                android:layout_gravity="center"
                android:padding="2dip" 
                />
            <View 
                style="@style/list_item_cell_seperator_layout" 
                />
            <TextView 
                android:id="@+id/stock_list_header_price_change_percentage"
                android:text="@string/stock_price_change_percent"
                android:layout_width="50dip" 
                android:layout_height="wrap_content"
                android:layout_gravity="center" 
                android:padding="2dip" 
                />
            <View 
                style="@style/list_item_cell_seperator_layout" 
                />
        TableRow>
    TableLayout>
LinearLayout>

是用来在每个单元格之间显示出一条垂直的分割线,使单元格之间相互分割开来。

第四步、定义ListItem的布局文件,stock_list_item.xml如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <TableLayout 
        android:id="@+id/stock_list_item_table_layout"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:stretchColumns="3">
        <TableRow 
            android:id="@+id/stock_list_row">
            <View 
                style="@style/list_item_cell_seperator_layout" 
                />
            <TextView 
                android:id="@+id/stock_code" 
                android:layout_width="60dip"
                android:layout_height="wrap_content" 
                android:layout_gravity="center"
                android:padding="2dip" />
            <View 
                style="@style/list_item_cell_seperator_layout" 
                />
            <TextView 
                android:id="@+id/stock_symbol"
                android:layout_width="1dip" 
                android:layout_height="wrap_content"
                android:layout_gravity="center" 
                android:padding="2dip" 
                />
            <View 
                style="@style/list_item_cell_seperator_layout" 
                />
            <TextView android:id="@+id/stock_last_price"
                android:layout_width="60dip" 
                android:layout_height="wrap_content"
                android:layout_gravity="center" 
                android:padding="2dip" 
                />
            <View 
                style="@style/list_item_cell_seperator_layout" 
                />
            <TextView 
                android:id="@+id/stock_change_price"
                android:layout_width="50dip" 
                android:layout_height="wrap_content"
                android:layout_gravity="center" 
                android:padding="2dip" 
                />
            <View 
                style="@style/list_item_cell_seperator_layout" 
                />
            <TextView 
                android:id="@+id/stock_change_percentage"
                android:layout_width="50dip" 
                android:layout_height="wrap_content"
                android:layout_gravity="center" 
                android:padding="2dip" 
                />
            <View 
                style="@style/list_item_cell_seperator_layout" 
                />
        TableRow>
    TableLayout>
LinearLayout>

第五步、定义stock list activity的layout文件stock_list.xml如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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">
    <View 
        style="@style/list_item_seperator_layout" 
        />
    <include 
        layout="@layout/stock_list_header" 
        />
    <View 
        style="@style/list_item_seperator_layout" 
        />
    <ListView 
        android:id="@+id/stock_list_view"
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:scrollingCache="true" 
        android:cacheColorHint="#00000000"
        android:fastScrollEnabled="true" 
        android:focusable="true"
        android:divider="@color/color_dark_grey" 
        android:dividerHeight="1dip" 
        />
LinearLayout>

是为了在Header的上下方显示一条线来分割header和list.可能有人会问,为什么这里不直接用ListView控件的header呢?

这是因为我们为了使ListView在滚动过程中header始终固定在List的最上方,不会随着ListView的滚动而消失。

到此为止,layout布局文件基本上定义完了,下面就是如何在代码中实现了。

StockListActivity.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package com.android.msoft.mfinance.ui;
  
import com.android.msoft.mfinance.R;
import com.android.msoft.mfinance.provider.Stock;
import com.android.msoft.mfinance.provider.StockMarket.StockMarketColumns;
import com.android.msoft.mfinance.ui.MFinancePreferenceActivity.BGColor;
import com.android.msoft.mfinance.ui.MFinancePreferenceActivity.TextSize;
import com.android.msoft.mfinance.ui.MFinancePreferenceActivity.UpDownColor;
  
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.WindowManager;
import android.widget.ListView;
import android.widget.TableRow;
import android.widget.TextView;
  
public class StockListActivity extends Activity {
  
    private static final String TAG = "com.android.msoft.mfinance.ui.StockListActivity";
    private SharedPreferences mPreference;
    private TextView mCodeTextView;
    private TextView mSymbolTextView;
    private TextView mLastPriceTextView;
    private TextView mPriceChangeTextView;
    private TextView mPriceChangePercentageTextView;
    private ListView mStockListView;
    private TableRow mStockListHeader;
    private float mTextSize;
  
    private int mBgColor;
    private int mDownTextColor;
    private int mUpTextColor;
    private Cursor mStockListCursor;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
  
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.stock_list);
  
        mPreference = PreferenceManager.getDefaultSharedPreferences(this);
  
        refreshDisplayPreference();
  
        mStockListHeader = (TableRow) findViewById(R.id.stock_list_header_row);
        mCodeTextView = (TextView) findViewById(R.id.stock_list_header_code);
        mSymbolTextView = (TextView) findViewById(R.id.stock_list_header_symbol);
        mLastPriceTextView = (TextView) findViewById(R.id.stock_list_header_last_price);
        mPriceChangeTextView = (TextView) findViewById(R.id.stock_list_header_price_change);
        mPriceChangePercentageTextView = (TextView) findViewById(R.id.stock_list_header_price_change_percentage);
  
        mStockListView = (ListView) findViewById(R.id.stock_list_view);
  
        refreshStockListHeader();
  
        mStockListCursor = getContentResolver().query(
                Stock.CONTENT_URI_STOCK_WITH_MARKET, null, null, null,
                StockMarketColumns.CHANGE_PRICE_PERCENT + " DESC");
  
        StockListAdapter listViewAdpater = new StockListAdapter(this,
                mStockListCursor);
        mStockListView.setAdapter(listViewAdpater);
    }
  
    @Override
    protected void onDestroy() {
        if (!mStockListCursor.isClosed()) {
            mStockListCursor.close();
        }
  
        super.onDestroy();
    }
  
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
  
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.stock_list_option_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }
  
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.stock_list_option_menu_settings:
            Intent intent = new Intent(this, MFinancePreferenceActivity.class);
            startActivity(intent);
            break;
        }
  
        return super.onOptionsItemSelected(item);
    }
  
    private void refreshDisplayPreference() {
  
        UpDownColor upAndDownColor = MFinancePreferenceActivity.UpDownColor
                .valueOf(mPreference.getString("up_down_color", "RED_GREEN"));
  
        if (0 == upAndDownColor.value) { // UP: RED DOWN: GREEN
            mUpTextColor = getResources().getColor(R.color.color_red);
            mDownTextColor = getResources().getColor(R.color.color_green);
        } else { // DOWN: RED UP: GREEN
            mUpTextColor = getResources().getColor(R.color.color_green);
            mDownTextColor = getResources().getColor(R.color.color_red);
        }
  
        TextSize textSize = MFinancePreferenceActivity.TextSize
                .valueOf(mPreference.getString("text_size", "NORMAL"));
        mTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                textSize.value, getResources().getDisplayMetrics());
  
        int colorResId = R.color.color_black;
        BGColor bgColor = MFinancePreferenceActivity.BGColor
                .valueOf(mPreference.getString("bg_color", "BLACK"));
  
        switch (bgColor.value) {
        case 0:
            colorResId = R.color.color_black;
            break;
  
        case 1:
            colorResId = R.color.color_white;
            break;
  
        default:
            Log.e(TAG, "invalid bg color");
        }
  
        mBgColor = getResources().getColor(colorResId);
    }
  
    public float getTextSize() {
        return mTextSize;
    }
  
    public int getBgColor() {
        return mBgColor;
    }
  
    public int getUpTextColor() {
        return mUpTextColor;
    }
  
    public int getDownTextColor() {
        return mDownTextColor;
    }
  
    private void refreshStockListHeader() {
  
        mCodeTextView.setTextSize(mTextSize);
        mSymbolTextView.setTextSize(mTextSize);
        mLastPriceTextView.setTextSize(mTextSize);
        mPriceChangeTextView.setTextSize(mTextSize);
        mPriceChangePercentageTextView.setTextSize(mTextSize);
  
        mStockListHeader.setBackgroundColor(mBgColor);
        mStockListView.setBackgroundColor(mBgColor);
    }
}

StockListAdapter.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.android.msoft.mfinance.ui;
  
import com.android.msoft.mfinance.provider.Stock.StockColumns;
import com.android.msoft.mfinance.provider.StockMarket.StockMarketColumns;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
  
public class StockListAdapter extends BaseAdapter {
  
    private static final String TAG = "com.android.msoft.mfinance.ui.StockListAdapter";
    private Cursor mStockListCursor;
    private Context mContext;
  
    private final int sCodeIndex;
    private final int sSymbolIndex;
    private final int sBoardIndex;
    private final int sLastPriceIndex;
    private final int sChangePriceIndex;
    private final int sChangePricePercentIndex;
  
    public StockListAdapter(Context context, Cursor cursor) {
        mStockListCursor = cursor;
        mContext = context;
  
        sCodeIndex = mStockListCursor.getColumnIndex(StockColumns.CODE);
        sSymbolIndex = mStockListCursor.getColumnIndex(StockColumns.SYMBOL);
        sBoardIndex = mStockListCursor.getColumnIndex(StockColumns.BOARD);
        sLastPriceIndex = mStockListCursor
                .getColumnIndex(StockMarketColumns.LAST_PRICE);
        sChangePriceIndex = mStockListCursor
                .getColumnIndex(StockMarketColumns.CHANGE_PRICE);
        sChangePricePercentIndex = mStockListCursor
                .getColumnIndex(StockMarketColumns.CHANGE_PRICE_PERCENT);
    }
  
    @Override
    public int getCount() {
        Log.d(TAG, "Stock list count:" + mStockListCursor.getCount());
        return mStockListCursor.getCount();
    }
  
    @Override
    public Object getItem(int position) {
        return null;
    }
  
    @Override
    public long getItemId(int position) {
        return position;
    }
  
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        StockListItem listItem;
  
        mStockListCursor.moveToPosition(position);
        if (null == convertView) {
            String code = mStockListCursor.getString(sCodeIndex);
            String symbol = mStockListCursor.getString(sSymbolIndex);
            String board = mStockListCursor.getString(sBoardIndex);
            float lastPrice = mStockListCursor.getFloat(sLastPriceIndex);
            float changePrice = mStockListCursor.getFloat(sChangePriceIndex);
            float changePercent = mStockListCursor
                    .getFloat(sChangePricePercentIndex);
  
            listItem = new StockListItem(mContext, code, symbol, board,
                    lastPrice, changePrice, changePercent);
        } else {
            listItem = (StockListItem) convertView;
        }
  
        return listItem;
    }
  
}

StockListItem.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.android.msoft.mfinance.ui;
  
import com.android.msoft.mfinance.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.TextView;
  
public class StockListItem extends LinearLayout {
  
    public StockListItem(Context context, String code, String symbol,
            String board, float lastPrice, float changePrice,
            float changePercent) {
        super(context);
  
        StockListActivity stockListActivity = (StockListActivity) context;
        float textSize = stockListActivity.getTextSize();
  
        LayoutInflater factory = LayoutInflater.from(context);
        factory.inflate(R.layout.stock_list_item, this);
  
        TextView codeTextView = (TextView) findViewById(R.id.stock_code);
        codeTextView.setTextSize(textSize);
        codeTextView.setText(code);
  
        TextView symbolTextView = (TextView) findViewById(R.id.stock_symbol);
        symbolTextView.setTextSize(textSize);
        symbolTextView.setText(symbol);
  
        TextView lastPriceTextView = (TextView) findViewById(R.id.stock_last_price);
        lastPriceTextView.setTextSize(textSize);
        lastPriceTextView.setText(Float.toString(lastPrice));
  
        TextView changePriceTextView = (TextView) findViewById(R.id.stock_change_price);
        changePriceTextView.setTextSize(textSize);
        changePriceTextView.setText(Float.toString(changePrice));
  
        TextView ChangePercentTextView = (TextView) findViewById(R.id.stock_change_percentage);
        ChangePercentTextView.setTextSize(textSize);
        ChangePercentTextView.setText(Float.toString(changePercent));
  
        if (changePrice > 0) {
            int textColor = stockListActivity.getUpTextColor();
  
            // codeTextView.setTextColor(textColor);
            // symbolTextView.setTextColor(textColor);
            lastPriceTextView.setTextColor(textColor);
            changePriceTextView.setTextColor(textColor);
            ChangePercentTextView.setTextColor(textColor);
        } else if (changePrice < 0) {
            int textColor = stockListActivity.getDownTextColor();
  
            // codeTextView.setTextColor(textColor);
            // symbolTextView.setTextColor(textColor);
            lastPriceTextView.setTextColor(textColor);
            changePriceTextView.setTextColor(textColor);
            ChangePercentTextView.setTextColor(textColor);
        }
    }
  
}

到此就大功告成了,这个例子我们是通过View来画线条分割各个单元格的,另外我们还可以通过定义不同的背景色,通过背景色来达到相似的效果,这个不难,就不写了。

你可能感兴趣的:(ListView实现漂亮的自定义表格实例)