ListView实现带标题栏效果(附源码)

我的实现思路是重写一个LinearLayout,在里面放一个标题栏,再在下面放一个ListView存放数据 ,  目前实现了文字列宽自动适应, 自动排版内容等功能 。

ListView实现带标题栏效果(附源码)

 我把整个功能写成了一个类,在需要用的时候只需要new出这个类就可以直接使用了

该类目前的所有方法:
/** 初始化带标题ListView. */
CListView(Context, String[], List<String[]>)
/** 整体有改变时,刷新显示. */
definedSetChanged()
/** 设置选中时的监听器. */
setOnItemClickListener(OnItemClickListener)
/** 设置行背景颜色, 多个颜色可以作为间隔色. */
setItemBackgroundColor(int...)
/** 数据总数. */
getCount()
/** 当前选中数据. */
getItem(int)
/** 设置当前选中位置. */
setSelectedPosition(int)
/** 当前选中位置. */
getSelectedPosition()
/** 设置被选中时的背景色. */
setSelectedBackgroundColor(int)
/** 设置标题背景色. */
setTitleBackgroundColor(int)
/** 设置标题文字颜色. */
setTitleTextColor(int)
/** 设置内容文字颜色. */
setContentTextColor(int)
/** 设置标题字体大小. */
setTitleTextSize(float)
/** 设置内容字体大小. */
setContentTextSize(float)
/** 设定哪列自动列宽 从0开始计算. */
setAutoColumnWidth(int)

这是我的代码,希望各位如果有什么好的建议都提出来,或者大家对其有修改也希望发给我一份:

  1 package cn.title.list;

  2 

  3 import java.util.ArrayList;

  4 import java.util.List;

  5 

  6 import android.app.Activity;

  7 import android.graphics.Color;

  8 import android.os.Bundle;

  9 import android.view.Menu;

 10 import android.view.MenuItem;

 11 import android.view.View;

 12 import android.widget.AdapterView;

 13 

 14 public class TitleListActivity extends Activity {

 15      

 16         TListView t_listView;

 17         List<String[]> list = new ArrayList<String[]>();

 18   

 19         public void onCreate(Bundle savedInstanceState) {

 20             super.onCreate(savedInstanceState);

 21             //setContentView(R.layout.main);

 22             

 23             makeData();

 24 

 25             String[] title = new String[] { "ID", "标题2", "标题3", "标题4", "标题5" };

 26 

 27             t_listView = new TListView(this, title, list);

 28             t_listView.setTitleTextColor(Color.GREEN);

 29             t_listView.setTitleBackgroundColor(Color.RED);

 30             // listView.setAutoColumnWidth(3);

 31             // listView.setItemBackgroundColor(Color.GREEN, Color.WHITE);

 32             t_listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

 33 

 34                  

 35                 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

 36                     String[] item = t_listView.getItem(position);

 37                     item[2] = "12312312312";

 38                     t_listView.definedSetChanged();

 39                 }

 40             });

 41             

 42 //            listView.definedSetChanged();

 43 

 44             setContentView(t_listView);  

 45         }

 46 

 47         /*

 48          * (non-Javadoc)

 49          * 

 50          * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)

 51          */

 52          

 53         public boolean onCreateOptionsMenu(Menu menu) {

 54             menu.add(0, 0, 0, "测试修改选中行");

 55             return true;

 56         }

 57 

 58         /*

 59          * (non-Javadoc)

 60          * 

 61          * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)

 62          */

 63          

 64         public boolean onOptionsItemSelected(MenuItem item) {

 65             switch (item.getItemId()) {

 66             case 0:

 67                 t_listView.setSelectedPosition(32);

 68                 break;

 69             }

 70             return true;

 71         }

 72 

 73         private void makeData() {

 74             list.add(new String[] { "1", "数据1.2", "数据1.3", "数据1.4" });

 75             list.add(new String[] { "2", "数据2.2", "数据2.3", "数据2.4", "数据2.5" });

 76             list.add(new String[] { "3", "数据3.2", "数据3.3", "数据3.4" });

 77             list.add(new String[] { "4", "数据4.2", "数据4.3", "数据4.4" });

 78             list.add(new String[] { "5", "数据5.2", "数据5.3", "数据5.4", "数据5.5" });

 79             list.add(new String[] { "6", "数据6.2", "数据6.3", "数据6.4" });

 80             list.add(new String[] { "7", "数据7.2", "数据7.3", "数据7.4", "数据7.5", "数据7.6" });

 81             list.add(new String[] { "8", "数据8.2", "数据8.3", "数据8.4" });

 82             list.add(new String[] { "9", "数据9.2", "数据9.3", "数据9.4" });

 83             list.add(new String[] { "10", "数据10.2", "数据10.3", "数据10.4", "数据10.5", "数据10.6", "数据10.7" });

 84             list.add(new String[] { "11", "数据11.2", "数据11.3", "数据11.4", "数据11.5" });

 85             list.add(new String[] { "12", "数据12.2", "数据12.3", "数据12.4", "数据12.5" });

 86             list.add(new String[] { "13", "数据13.2", "数据13.3", "数据13.4", "数据13.5" });

 87             list.add(new String[] { "14", "数据14.2", "数据14.3", "数据14.4", "数据14.5" });

 88             list.add(new String[] { "15", "数据15.2", "数据15.3", "数据15.4", "数据15.5" });

 89             list.add(new String[] { "16", "数据16.2", "数据16.3", "数据16.4", "数据16.5" });

 90             list.add(new String[] { "17", "数据17.2", "数据17.3", "数据17.4", "数据17.5" });

 91             list.add(new String[] { "18", "数据18.2", "数据18.3", "数据18.4", "数据18.5" });

 92             list.add(new String[] { "19", "数据19.2", "数据19.3", "数据19.4", "数据19.5" });

 93             list.add(new String[] { "20", "数据20.2", "数据20.3", "数据20.4", "数据20.5" });

 94             list.add(new String[] { "21", "数据21.2", "数据21.3", "数据21.4", "数据21.5" });

 95             list.add(new String[] { "22", "数据22.2", "数据22.3", "数据22.4", "数据22.5" });

 96             list.add(new String[] { "23", "数据23.2", "数据23.3", "数据23.4", "数据23.5" });

 97             list.add(new String[] { "24", "数据24.2", "数据24.3", "数据24.4", "数据24.5" });

 98             list.add(new String[] { "25", "数据25.2", "数据25.3", "数据25.4", "数据25.5" });

 99             list.add(new String[] { "26", "数据26.2" });

100             list.add(new String[] { "27", "数据27.2", "数据27.3", "数据27.4", "数据27.5" });

101             list.add(new String[] { "28", "数据28.2", "数据28.3", "数据28.4", "数据28.5" });

102             list.add(new String[] { "29", "数据29.2", "数据29.3", "数据29.4", "数据29.5" });

103             list.add(new String[] { "30", "数据12.2", "数据12.3", "数据12.4", "数据12.5" });

104             list.add(new String[] { "31", "数据13.2", "数据13.3", "数据13.4", "数据13.5" });

105             list.add(new String[] { "32", "数据14.2", "数据14.3", "数据14.4", "数据14.5" });

106             list.add(new String[] { "33", "数据15.2", "数据15.3", "数据15.4", "数据15.5" });

107             list.add(new String[] { "34", "数据16.2", "数据16.3", "数据16.4", "数据16.5" });

108             list.add(new String[] { "35", "数据17.2", "数据17.3", "数据17.4", "数据17.5" });

109             list.add(new String[] { "36", "数据18.2", "数据18.3" });

110             list.add(new String[] { "37", "数据19.2", "数据19.3", "数据19.4", "数据19.5" });

111             list.add(new String[] { "38", "数据20.2", "数据20.3", "数据20.4", "数据20.5" });

112             list.add(new String[] { "39", "数据21.2", "数据21.3", "数据21.4", "数据21.5" });

113             list.add(new String[] { "40", "数据22.2", "数据22.3", "数据22.4", "数据22.5" });

114             list.add(new String[] { "41", "数据23.2", "数据23.3", "数据23.4", "数据23.5" });

115             list.add(new String[] { "42", "数据24.2", "数据24.3", "数据24.4", "数据24.5" });

116             list.add(new String[] { "43", "数据25.2", "数据25.3", "数据25.4", "数据25.5" });

117             list.add(new String[] { "44", "数据26.2", "数据26.3", "数据26.4", "数据26.5" });

118             list.add(new String[] { "45", "数据27.2", "数据27.3", "数据27.4", "数据27.5" });

119             list.add(new String[] { "46", "数据28.2", "数据28.3", "数据28.4", "数据28.5" });

120             list.add(new String[] { "47", "数据29.2", "数据29.3", "数据29.4", "数据29.5" });

121         }

122      

123 }

 

  1 package cn.title.list;

  2  

  3     import java.util.List;

  4 

  5     import android.content.Context;

  6     import android.graphics.Canvas;

  7     import android.graphics.Color;

  8     import android.graphics.Paint;

  9     import android.view.Gravity;

 10     import android.view.View;

 11     import android.view.ViewGroup;

 12     import android.widget.AdapterView;

 13     import android.widget.BaseAdapter;

 14     import android.widget.LinearLayout;

 15     import android.widget.ListView;

 16     import android.widget.TextView;

 17 

 18     /**

 19      * 标题ListView     TListView

 20      * @author  

 21      * 

 22      */

 23     public class TListView extends LinearLayout {

 24 

 25         private static LayoutParams FILL_FILL_LAYOUTPARAMS = new LayoutParams(LayoutParams.FILL_PARENT,

 26                 LayoutParams.FILL_PARENT, 1);

 27         private static LayoutParams WAP_WAP_LAYOUTPARAMS = new LayoutParams(LayoutParams.WRAP_CONTENT,

 28                 LayoutParams.WRAP_CONTENT);

 29 

 30         private static Paint BLACK_PAINT = new Paint();

 31         private static Paint WHITE_PAINT = new Paint();

 32         static {

 33             WHITE_PAINT.setColor(Color.WHITE);

 34             BLACK_PAINT.setColor(Color.BLACK);

 35         }

 36 

 37         private CAdapter cAdapter;

 38 

 39         /** 标题空间. */

 40         private LinearLayout titleLayout;

 41         private String[] title;

 42 

 43         private ListView listView;

 44         /** 数据. */

 45         private List<String[]> data;

 46 

 47         /** 列宽数据. */

 48         private int[] itemWidth;

 49 

 50         /** 当前选中行. */

 51         private int selectedPosition = -1;

 52         /** 自动列宽列. */

 53         private int autoWidthIndex = -1;

 54 

 55         private AdapterView.OnItemClickListener onItemClickListener;

 56 

 57         /** 行背景颜色. */

 58         private int[] rowsBackgroundColor;

 59         /** 选中行背景颜色. */

 60         private int selectedBackgroundColor = Color.argb(200, 224, 243, 250);

 61         /** 标题背景颜色. */

 62         private int titleBackgroundColor;

 63         /** 标题字体颜色. */

 64         private int titleTextColor = Color.argb(255, 100, 100, 100);

 65         /** 内容字体颜色. */

 66         private int contentTextColor = Color.argb(255, 100, 100, 100);

 67         /** 标题字体大小. */

 68         private float titleTextSize = 0;

 69         /** 内容字体大小. */

 70         private float contentTextSize = 0;

 71 

 72         /**

 73          * 初始化带标题ListView

 74          * 

 75          * @param context

 76          *            父级上下文

 77          * @param title

 78          *            标题数组

 79          * @param data

 80          *            内容列表

 81          */

 82         public TListView(Context context, String[] title, List<String[]> data) {

 83             super(context);

 84 

 85             this.title = title;

 86             this.data = data;

 87 

 88             // 设定纵向布局

 89             setOrientation(VERTICAL);

 90             // 设定背景为白色

 91             setBackgroundColor(Color.WHITE);

 92 

 93             // 预先设定好每列的宽

 94             this.itemWidth = new int[title.length];

 95             autoWidthIndex = this.itemWidth.length - 1;

 96             // 计算列宽

 97             calcColumnWidth();

 98 

 99             // 添加title位置

100             titleLayout = new LinearLayout(getContext());

101             titleLayout.setBackgroundColor(Color.parseColor("#CCCCCC"));

102             addView(titleLayout);

103             // 绘制标题面板

104             drawTitleLayout();

105 

106             // 添加listview

107             listView = new ListView(getContext());

108             listView.setPadding(0, 2, 0, 0);

109             cAdapter = new CAdapter();

110             listView.setAdapter(cAdapter);

111             listView.setCacheColorHint(0);

112             listView.setLayoutParams(FILL_FILL_LAYOUTPARAMS);

113             listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

114 

115                 

116                 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

117                     if (onItemClickListener != null)

118                         onItemClickListener.onItemClick(parent, view, position, id);

119                     setSelectedPosition(position);

120                     selectedPosition = position;

121                     cAdapter.notifyDataSetChanged();

122                 }

123             });

124             addView(listView);

125         }

126 

127         /**

128          * 整体有改变时,刷新显示

129          */

130         public void definedSetChanged() {

131             calcColumnWidth();

132             drawTitleLayout();

133             cAdapter.notifyDataSetChanged();

134         }

135         

136         /**

137          * 设置选中时的监听器

138          * 

139          * @param onItemClickListener

140          */

141         public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {

142             this.onItemClickListener = onItemClickListener;

143         }

144 

145         /**

146          * 设置行背景颜色, 多个颜色可以作为间隔色

147          * 

148          * @param color

149          *            行背景颜色,可以为多个

150          */

151         public void setItemBackgroundColor(int... color) {

152             rowsBackgroundColor = color;

153         }

154 

155         /**

156          * 数据总数

157          */

158         public int getCount() {

159             if (data == null)

160                 return 0;

161             return data.size();

162         }

163 

164         /**

165          * 当前选中数据

166          * 

167          * @param position

168          * @return

169          */

170         public String[] getItem(int position) {

171             if (data == null)

172                 return null;

173             return data.get(position);

174         }

175 

176         /**

177          * 设置当前选中位置

178          * 

179          * @return

180          */

181         public void setSelectedPosition(int selectedPosition) {

182             this.selectedPosition = selectedPosition;

183         }

184 

185         /**

186          * 当前选中位置

187          * 

188          * @return

189          */

190         public int getSelectedPosition() {

191             return selectedPosition;

192         }

193 

194         /**

195          * 设置被选中时的背景色

196          * 

197          * @param color

198          */

199         public void setSelectedBackgroundColor(int color) {

200             selectedBackgroundColor = color;

201         }

202 

203         /** 

204          * 设置标题背景色.

205          * @param color

206          */

207         public void setTitleBackgroundColor(int color) {

208             titleBackgroundColor = color;

209             titleLayout.setBackgroundColor(titleBackgroundColor);

210         }

211         

212         /**

213          * 设置标题文字颜色

214          * 

215          * @param color

216          */

217         public void setTitleTextColor(int color) {

218             titleTextColor = color;

219             for (int i = 0; i < titleLayout.getChildCount(); i++) {

220                 ((TextView) titleLayout.getChildAt(i)).setTextColor(titleTextColor);

221             }

222         }

223 

224         /**

225          * 设置内容文字颜色

226          * 

227          * @param color

228          */

229         public void setContentTextColor(int color) {

230             contentTextColor = color;

231         }

232 

233         /**

234          * 设置标题字体大小

235          * 

236          * @param szie

237          */

238         public void setTitleTextSize(float szie) {

239             titleTextSize = szie;

240         }

241 

242         /**

243          * 设置内容字体大小

244          * 

245          * @param szie

246          */

247         public void setContentTextSize(float szie) {

248             contentTextSize = szie;

249         }

250 

251         /**

252          * 

253          * 设定哪列自动列宽 从0开始计算

254          * 

255          * @param index

256          */

257         public void setAutoColumnWidth(int index) {

258             autoWidthIndex = index;

259             for (int i = 0; i < titleLayout.getChildCount(); i++) {

260                 TextView tv = ((TextView) titleLayout.getChildAt(i));

261                 if (i == autoWidthIndex)

262                     tv.setLayoutParams(FILL_FILL_LAYOUTPARAMS);

263                 else {

264                     tv.setLayoutParams(WAP_WAP_LAYOUTPARAMS);

265                     tv.setWidth(itemWidth[i]);

266                 }

267             }

268         }

269 

270         /**

271          * 绘制标题

272          */

273         private void drawTitleLayout() {

274             titleLayout.removeAllViews();

275             for (int i = 0; i < title.length; i++) {

276                 TextView tv = new CTextView(titleLayout.getContext());

277                 tv.setTextColor(titleTextColor);

278                 tv.setGravity(Gravity.CENTER);

279                 tv.setText(title[i]);

280                 if (titleTextSize > 0) {

281                     tv.setTextSize(titleTextSize);

282                 }

283                 tv.setPadding(5, 0, 5, 0);

284                 if (i == autoWidthIndex)

285                     tv.setLayoutParams(TListView.FILL_FILL_LAYOUTPARAMS);

286                 else {

287                     tv.setWidth(itemWidth[i]);

288                 }

289                 titleLayout.addView(tv);

290             }

291         }

292 

293         /**

294          * 计算列宽

295          * 

296          * @return 是否有改动

297          */

298         private boolean calcColumnWidth() {

299             boolean result = false;

300 

301             float textSize = new TextView(getContext()).getTextSize();

302 

303             // 计算标题列宽

304             for (int i = 0; i < itemWidth.length; i++) {

305                 int w = (int) TListView.GetPixelByText((titleTextSize > 0) ? titleTextSize : textSize, title[i]);

306                 if (itemWidth[i] < w) {

307                     itemWidth[i] = w;

308                     result = true;

309                 }

310             }

311 

312             // 计算内容列宽

313             if (contentTextSize > 0) {

314                 textSize = contentTextSize;

315             }

316             for (int i = 0; i < data.size(); i++) {

317                 for (int j = 0; j < itemWidth.length && j < data.get(i).length; j++) {

318                     int w = (int) TListView.GetPixelByText(textSize, data.get(i)[j]);

319                     if (itemWidth[j] < w) {

320                         itemWidth[j] = w;

321                         result = true;

322                     }

323                 }

324             }

325             return result;

326         }

327 

328         /**

329          * 计算字符串所占像素

330          * 

331          * @param textSize

332          *            字体大小

333          * @param text

334          *            字符串

335          * @return 字符串所占像素

336          */

337         private static int GetPixelByText(float textSize, String text) {

338             Paint mTextPaint = new Paint();

339             mTextPaint.setTextSize(textSize); // 指定字体大小

340             mTextPaint.setFakeBoldText(true); // 粗体

341             mTextPaint.setAntiAlias(true); // 非锯齿效果

342 

343             return (int) (mTextPaint.measureText(text) + textSize);

344         }

345 

346         /**

347          * 主要用的Adapter

348          * 

349          * @author Cdisk

350          * 

351          */

352         class CAdapter extends BaseAdapter {

353 

354             /*

355              * (non-Javadoc)

356              * 

357              * @see android.widget.Adapter#getCount()

358              */

359             

360             public int getCount() {

361                 if (data == null)

362                     return 0;

363                 return data.size();

364             }

365 

366             /*

367              * (non-Javadoc)

368              * 

369              * @see android.widget.Adapter#getItem(int)

370              */

371             

372             public Object getItem(int position) {

373                 if (data == null)

374                     return null;

375                 return data.get(position);

376             }

377 

378             /*

379              * (non-Javadoc)

380              * 

381              * @see android.widget.Adapter#getItemId(int)

382              */

383              

384             public long getItemId(int position) {

385                 return 0;

386             }

387 

388             /*

389              * (non-Javadoc)

390              * 

391              * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)

392              */

393              

394             public View getView(int position, View convertView, ViewGroup parent) {

395 

396                 // 初始化主layout

397                 LinearLayout contextLayout = new LinearLayout(TListView.this.getContext());

398 

399                 String[] dataItem = data.get(position);

400 

401                 if (getSelectedPosition() == position) { // 为当前选中行

402                     contextLayout.setBackgroundColor(selectedBackgroundColor);

403                 } else if (rowsBackgroundColor != null && rowsBackgroundColor.length > 0) {

404                     contextLayout.setBackgroundColor(rowsBackgroundColor[position % rowsBackgroundColor.length]);

405                 }

406 

407                 for (int i = 0; i < title.length; i++) {

408                     TextView tv = new CTextView(contextLayout.getContext());

409                     tv.setTextColor(contentTextColor);

410                     tv.setGravity(Gravity.CENTER);

411                     if (i < dataItem.length) {

412                         tv.setText(dataItem[i]);

413                     }

414                     if (i == autoWidthIndex)

415                         tv.setLayoutParams(TListView.FILL_FILL_LAYOUTPARAMS);

416                     else {

417                         tv.setWidth(itemWidth[i]);

418                     }

419                     if (contentTextSize > 0) {

420                         tv.setTextSize(contentTextSize);

421                     }

422                     contextLayout.addView(tv);

423                 }

424 

425                 return contextLayout;

426             }

427 

428         }

429 

430         /**

431          * 重写的TextView

432          * 

433          * @author Cdisk

434          */

435         class CTextView extends TextView {

436 

437              

438             protected void onDraw(Canvas canvas) {

439                 super.onDraw(canvas);

440                 // Top

441                 canvas.drawLine(0, 0, this.getWidth() - 1, 0, WHITE_PAINT);

442                 // Left

443                 canvas.drawLine(0, 0, 0, this.getHeight() - 1, WHITE_PAINT);

444                 // Right

445                 canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1, this.getHeight() - 1, BLACK_PAINT);

446                 // Buttom

447                 canvas.drawLine(0, this.getHeight() - 1, this.getWidth() - 1, this.getHeight() - 1, BLACK_PAINT);

448             }

449 

450             public CTextView(Context context) {

451                 super(context);

452             }

453         }

454 

455     }

456 

457  

 

 main.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="fill_parent"

    android:orientation="vertical" >



    <!--

    <HorizontalScrollView android:id="@+id/HorizontalScrollView01" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1" android:fillViewport="true">

<LinearLayout android:id="@+id/LinearLayout01" android:layout_height="fill_parent" android:layout_width="fill_parent"><ListView android:id="@+id/listView" android:layout_width="fill_parent" android:layout_height="fill_parent">

</ListView></LinearLayout>

</HorizontalScrollView>



    -->



    <ListView

        android:id="@+id/listView"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:layout_weight="1" >

    </ListView>



    <Button

        android:id="@+id/btnImport"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:layout_weight="0"

        android:text="导入" >

    </Button>



</LinearLayout>

  

 

 

 源码下载:

点击下载

 

你可能感兴趣的:(ListView)