Android自定义控件继承ViewGrop实现一个GridView的显示效果
来源:互联网 发布:爱淘宝现金红包 编辑:程序博客网 时间:2024/04/27 23:22
View类和ViewGroup类介绍
android中所有的UI控件(button,textView,checkbox等等)基类都View类,android中的五种布局(LinearLayout ,RelativeLayout ,FrameLayout ,TableLayout ,AbsoluteLayout)都是View的容器,我们平常在XML文件中写的布局,定义的那些View都是需要VIew容器去包装它们,包括View控件之间的排版,控件与控件之间的间距等。例如LinearLayout就是将你定义的那些VIew控件按照线性的布局方式去排版。
ViewGroup类就是VIew容器的基类,LinearLayout ,RelativeLayout ,FrameLayout ,TableLayout ,AbsoluteLayout都是继承与ViewGroup。所以我们可以写一个自己的类去继承ViewGroup,这样我们的类就是一个View的容器了。我们写的UI控件就可以定义在我们自己的View容器中。
本文的例子就是继承于ViewGroup实现一个GridView排版效果的容器。
继承ViewGroup类主要是要覆写它的 onMeasure(),onLayout()这两个方法,onMeasure()方法用于测量每个子View的大小尺寸,onLayout()方法用于确定子View在布局中的位置。
DEMO:
<pre name="code" class="java">package cn.mmb.view;import static android.view.View.MeasureSpec.EXACTLY;import static android.view.View.MeasureSpec.makeMeasureSpec;import java.util.Iterator;import com.mmb.demo.R;import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;public class MyGridLayout extends ViewGroup {public final String TAG = "MyGridLayout";public static int DEFAULT_COLUMS = 2;public static int DEFAULT_HORIZONTAL_SPACING = 20;public static int DEFAULT_VERTICAL_SPACING = 20;public static int DEFAULT_ITEM_HEIGHT = 40;private int mHorizontalSpacing = 0;private int mVerticalSpacing = 0;private int colums = DEFAULT_COLUMS;private int mMaxChildWidth = 0;private int mMaxChildHeight = 0;private int count = 0;private int mItemHeight = 0;private GridAdatper adapter;public MyGridLayout(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);if (attrs != null) {TypedArray typedArray = getContext().obtainStyledAttributes(attrs,R.styleable.MyGridLayout);colums = typedArray.getInteger(R.styleable.MyGridLayout_numColumns,DEFAULT_COLUMS);mHorizontalSpacing = (int) typedArray.getInteger(R.styleable.MyGridLayout_horizontal_spacing,DEFAULT_HORIZONTAL_SPACING);mVerticalSpacing = (int) typedArray.getInteger(R.styleable.MyGridLayout_vertical_spacing,DEFAULT_VERTICAL_SPACING);mItemHeight = (int) typedArray.getInteger(R.styleable.MyGridLayout_itemHeight, DEFAULT_ITEM_HEIGHT);}}public MyGridLayout(Context context, AttributeSet attrs) {this(context, attrs, 0);}public MyGridLayout(Context context) {this(context, null);}/** * @return item Horizontal Spacing */public int getHorizontalSpacing() {return mHorizontalSpacing;}/** * set item Horizontal Spacing * * @param mHorizontalSpacing */public void setHorizontalSpacing(int mHorizontalSpacing) {this.mHorizontalSpacing = mHorizontalSpacing;}/** * @return item Vertical Spacing */public int getVerticalSpacing() {return mVerticalSpacing;}/** * set item Vertical Spacing * * @param mVerticalSpacing */public void setVerticalSpacing(int mVerticalSpacing) {this.mVerticalSpacing = mVerticalSpacing;}/** * @return item height */public int getItemHeight() {return mItemHeight;}/** * set item height * * @param mItemHeight */public void setItemHeight(int mItemHeight) {this.mItemHeight = mItemHeight;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {mMaxChildWidth = 0;mMaxChildHeight = 0;int modeW = 0, modeH = 0;if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED) {modeW = MeasureSpec.UNSPECIFIED;}if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.UNSPECIFIED) {modeH = MeasureSpec.UNSPECIFIED;}final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), modeW);final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec), modeH);count = getChildCount();if (count == 0) {super.onMeasure(childWidthMeasureSpec, childHeightMeasureSpec);return;}for (int i = 0; i < count; i++) {final View child = getChildAt(i);if (child.getVisibility() == GONE) {continue;}child.measure(childWidthMeasureSpec, childHeightMeasureSpec);mMaxChildWidth = Math.max(mMaxChildWidth, child.getMeasuredWidth());mMaxChildHeight = Math.max(mMaxChildHeight,child.getMeasuredHeight());}setMeasuredDimension(resolveSize(mMaxChildWidth, widthMeasureSpec),resolveSize(mMaxChildHeight, heightMeasureSpec));}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {int height = b - t; // The height of the layout areaint width = r - l; // The width of the layout area// Calculate the number of rowsint rows = count % colums == 0 ? count / colums : count / colums + 1;if (count == 0) {return;}// Calculate every item widthint gridW = (width - (colums + 1) * mHorizontalSpacing) / colums;// item heightint gridH = mItemHeight; // int gridH = (height - mVerticalSpacing * rows) / rows;int left = 0;int top = mVerticalSpacing;for (int i = 0; i < rows; i++) {// Iterator the elements of each rowfor (int j = 0; j < colums; j++) {View child = this.getChildAt(i * colums + j);if (child == null) {return;}left = j * gridW + j * mHorizontalSpacing + mHorizontalSpacing;/** * If the current layout is not the same width and width * measurements, the direct use of re-measuring the width of the * current layout */if (gridW != child.getMeasuredWidth()|| gridH != child.getMeasuredHeight()) {child.measure(makeMeasureSpec(gridW, EXACTLY),makeMeasureSpec(gridH, EXACTLY));}/** * set current child view layout */child.layout(left, top, left + gridW, top + gridH); }top += gridH + mVerticalSpacing; // next rows}}public interface GridAdatper {View getView(int index);int getCount();}/** * set adapter * * @param adapter */public void setGridAdapter(GridAdatper adapter) {this.adapter = adapter;int size = adapter.getCount();for (int i = 0; i < size; i++) {addView(adapter.getView(i)); // addView}}public interface OnItemClickListener {void onItemClick(View v, int index);}/** * set Item Click Listener * * @param click */public void setOnItemClickListener(final OnItemClickListener click) {if (this.adapter == null)return;for (int i = 0; i < adapter.getCount(); i++) {final int index = i;View view = getChildAt(i);view.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {click.onItemClick(v, index);}});}}}
布局(activity_main.xml)中使用已经写好的View容器
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#303030" android:orientation="vertical" > <cn.mmb.view.MyGridLayout android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#1e1d1d" android:orientation="vertical" app:horizontal_spacing="30" app:vertical_spacing="20" app:itemHeight="60" app:numColumns="3"> </cn.mmb.view.MyGridLayout></LinearLayout>最后在Activity中
package com.mmb.demo;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;import org.apache.http.HttpResponse;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import cn.mmb.view.MyGridLayout;import com.mmb.demo.domin.MyColor;import com.mmb.demo.util.HttpUtil;import com.mmb.demo.util.Utils;import android.os.AsyncTask;import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.view.View;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity {private static final String MREQUESTPATH = "http://192.168.3.105:8080/demo/json.txt";private List<MyColor> mColorList;private MyGridLayout mGridLayout;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mColorList = new ArrayList<MyColor>();Utils.computeScreenDimen(this);mGridLayout = (MyGridLayout) findViewById(R.id.list);mGridLayout.setVerticalSpacing(Utils.uiHeightPxToScreenPx(30));mGridLayout.setHorizontalSpacing(Utils.uiWidthPxToScreenPx(40));mGridLayout.setItemHeight(Utils.uiHeightPxToScreenPx(100));new myWorkAsyncTask().execute();}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main, menu);return true;}class myWorkAsyncTask extends AsyncTask<Void, Void, Void> {private static final String TAG = "myWorkAsyncTask";@Overrideprotected Void doInBackground(Void... params) {String data = getJsonData(MREQUESTPATH);if (data != null) {parseJson(data);}return null;}private void parseJson(String data) {try {JSONObject jsonObject = new JSONObject(data);JSONArray jsonArray = jsonObject.getJSONArray("array");for (int i = 0; i < jsonArray.length(); i++) {JSONObject object = (JSONObject) jsonArray.get(i);int id = object.getInt("subId");String name = object.getString("name");mColorList.add(new MyColor(id, name));// Log.i (TAG, name);}} catch (JSONException e) {e.printStackTrace();}}private String getJsonData(String mRequestPath) {HttpResponse response = null;BufferedReader lineReader = null;try {response = HttpUtil.getHttpResponse(mRequestPath);int rescode = response.getStatusLine().getStatusCode();if (rescode == 200) {String line = null;StringBuilder builder = new StringBuilder();lineReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));while ((line = lineReader.readLine()) != null) {builder.append(line);}return builder.toString();}} catch (Exception e) {} finally {if (lineReader != null) {try {lineReader.close();} catch (IOException e) {e.printStackTrace();}}}return null;}@Overrideprotected void onPostExecute(Void result) {super.onPostExecute(result);mGridLayout.setGridAdapter(new cn.mmb.view.MyGridLayout.GridAdatper() {@Overridepublic View getView(int index) {View view = getLayoutInflater().inflate(R.layout.actions_item, null);TextView tv = (TextView) view.findViewById(R.id.tv);tv.setText(mColorList.get(index).getName());return view;}@Overridepublic int getCount() {return mColorList.size();}});mGridLayout.setOnItemClickListener(new cn.mmb.view.MyGridLayout.OnItemClickListener() {@Overridepublic void onItemClick(View v, int index) {Toast.makeText(getApplicationContext(),"item=" + index, Toast.LENGTH_SHORT).show();}});}}}运行结果:其子View item的排列效果类似于GridView。
0 0
- Android自定义控件继承ViewGrop实现一个GridView的显示效果
- Android自定义控件10----继承View实现水波纹效果
- Android自定义控件StaggeredGridView-瀑布流效果的GridView
- Android自定义控件StaggeredGridView-瀑布流效果的GridView
- 通过GridView实现一个自定义的一个日历控件
- android自定义控件系列教程----继承ViewGroup实现带阻力效果的可回弹的SrollView
- Android 自动换行自定义ViewGrop
- 使用viewGrop自定义轮播图中实现图片自适应手机屏幕的宽度
- android初学------设置ViewGrop下面的控件失效
- Android自定义控件之实现类似文件夹顶部的层层显示的横栏效果
- 继承PictureBox显示GIF的自定义控件实现
- 继承自ViewPager的支持多页显示GridView的自定义控件
- Android开发深化之关于自定义GridView控件的实现
- Android 自定义dialog,实现右上角显示一个控件按钮
- android继承View实现复杂的自定义控件(1)
- Android GridView控件自定义
- GridView控件自定义分页的实现
- Android学习之动画效果的实现、自定义控件皮肤
- C#中Math的使用总结
- XAML中AppBar的使用
- Android 颜色渲染(九) PorterDuff及Xfermode详解
- C#中文件和byte[]互换问题
- jquery实现浏览器滚动条往下时自动加载数据
- Android自定义控件继承ViewGrop实现一个GridView的显示效果
- Myeclipse中Java编程为类、方法等添加注释说明方法
- 搜索引擎 (一)全文资源检索框架Lucene
- 使用工作流更新子记录
- 搬寝室(HDU1421)
- POJ 1159 Palindrome
- 黑马程序员:多线程学习总结
- 杭电 2063 过山车
- POJ 3041 Asteroids (匈牙利算法)