使用ListView控件实现漂亮的自定义表格效果实例

使用ListView实现股票行情显示效果图如下,红色表示股价上涨,绿色表示股价下跌。

使用ListView控件实现漂亮的自定义表格效果实例_第1张图片

第1步,定义color.xml如下
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <color name="color_dark_grey">#808080</color>
    <color name="color_black">#000000</color>
    <color name="color_green">#00FF00</color>
    <color name="color_red">#FF0000</color>
    <color name="color_white">#FFFFFF</color>

</resources>

第2步,定义style.xml文件如下
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- Define the list items style begin -->
    <style name="list_item_seperator_layout">
        <item name="android:layout_width">fill_parent</item>
        <item name="android:layout_height">1dip</item>
        <item name="android:background">@color/color_dark_grey</item>
    </style>

    <style name="list_item_cell_seperator_layout">
        <item name="android:layout_width">1dip</item>
        <item name="android:layout_height">fill_parent</item>
        <item name="android:background">@color/color_dark_grey</item>
    </style>

    <!-- Define the list items style end -->
</resources>

第3步,定义ListHeader的layout文件,stock_list_header.xml
<?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>
<View style="@style/list_item_cell_seperator_layout"/>是用来在每个单元格之间显示出一条垂直的分割线,使单元格之间相互分割开来。 

第4步,定义ListItem的布局文件,stock_list_item.xml如下
<?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>

第5步,定义stock list activity的layout文件stock_list.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"
    >

    <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>
<View style="@style/list_item_seperator_layout"/>是为了在Header的上下方显示一条线来分割header和list.可能有人会问,为什么这里不直接用ListView控件的header呢? 这是因为我们为了使ListView在滚动过程中header始终固定在List的最上方,不会随着ListView的滚动而消失

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

StockListActivity.java
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
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
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来画线条分割各个单元格的,另外我们还可以通过定义不同的背景色,通过背景色来达到相似的效果,这个不难,就不写了


你可能感兴趣的:(android,ListView,list,header,layout,encoding)