自定义布局实现自动换行
来源:互联网 发布:智能小车pid算法 编辑:程序博客网 时间:2024/05/17 03:08
RT:
先上图
在Hot Keywords下面实现的是自动换行的效果
直接附上代码
如下
自定义布局CustomListView
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 99100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
public class CustomListView extends RelativeLayout { private String TAG = CustomListView.class.getSimpleName(); private CustomAdapter myCustomAdapter; public CustomListView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onLayout(boolean arg0, int argLeft, int argTop, int argRight, int argBottom) { Log.i(TAG, "L:"+argLeft+" T:"+argTop+" R:"+argRight+" B:"+argBottom); final int count = getChildCount(); int row=0; int lengthX=0; int lengthY=0; for(int i=0;i<count;i++){ final View child = this.getChildAt(i); int width = child.getMeasuredWidth(); int height = child.getMeasuredHeight(); if(lengthX == 0){ lengthX += width; }else{ lengthX += (width+getDividerWidth()); } if((i == 0 && lengthX<=argRight)){ lengthY += height; } if(lengthX>argRight){ lengthX = width; lengthY += getDividerHeight()+height; row++; child.layout(lengthX-width, lengthY-height, lengthX, lengthY); }else{ child.layout(lengthX-width, lengthY-height, lengthX, lengthY); } } android.view.ViewGroup.LayoutParams lp = CustomListView.this.getLayoutParams(); lp.height = lengthY; CustomListView.this.setLayoutParams(lp); if(isAddChildType()){ new Thread(new RefreshCustomThread()).start(); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(width, height); for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } private static boolean addChildType; final static boolean isAddChildType() { return addChildType; } public static void setAddChildType(boolean addChildType) { CustomListView.addChildType = addChildType; } private int dividerHeight = 0; final int getDividerHeight() { return dividerHeight; } public void setDividerHeight(int dividerHeight) { this.dividerHeight = dividerHeight; } private int dividerWidth = 0; final int getDividerWidth() { return dividerWidth; } public void setDividerWidth(int dividerWidth) { this.dividerWidth = dividerWidth; } public void setAdapter(CustomAdapter adapter){ this.myCustomAdapter = adapter; setAddChildType(true); adapter.notifyCustomListView(CustomListView.this); } /** * * @param listener */ public void setOnItemClickListener(OnItemClickListener listener){ myCustomAdapter.setOnItemClickListener(listener); } /** * Corresponding Item long click event * * @param listener */ public void setOnItemLongClickListener(OnItemLongClickListener listener){ myCustomAdapter.setOnItemLongClickListener(listener); } private final Handler handler = new Handler(Looper.getMainLooper()){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); try{ if(msg.getData().containsKey("getRefreshThreadHandler")){ setAddChildType(false); myCustomAdapter.notifyCustomListView(CustomListView.this); } }catch(Exception e){ Log.w(TAG, e); } } }; private final class RefreshCustomThread implements Runnable{ @Override public void run() { Bundle b = new Bundle(); try{ Thread.sleep(50); }catch(Exception e){ }finally{ b.putBoolean("getRefreshThreadHandler", true); sendMsgHanlder(handler, b); } } } private final void sendMsgHanlder(Handler handler,Bundle data){ Message msg = handler.obtainMessage(); msg.setData(data); handler.sendMessage(msg); }}
CustomAdapter
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 99100101102103104105106107108109110111112113114115116
public class CustomAdapter{ private String TAG = CustomAdapter.class.getSimpleName(); private View myView; private ViewGroup myViewGroup; private CustomListView myCustomListView; private OnItemClickListener listener; private OnItemLongClickListener longListener; public int getCount() { return 0; } public Object getItem(int position) { return null; } public long getItemId(int position) { return 0; } public View getView(final int position, View convertView, ViewGroup parent) { return null; } /** * * Add all the View controls to the custom SexangleViewList * When you use this SexangleViewList should be instantiated first and then call * Because here is not intercept and throw such as null pointer exception * The name is called mySexangleView View passed in must be empty * Of course the ViewGroup transfer time must also be empty * */ private final void getAllViewAddSexangle(){ this.myCustomListView.removeAllViews(); for(int i = 0 ; i < getCount() ; i++){ View viewItem = getView(i, this.myView, this.myViewGroup); this.myCustomListView.addView(viewItem,i); } } /** * * The refresh SexangleListView interface * Here is set to True representative will execute reset CustomListView twice * This method is called before, please first instantiation mySexangleListView * Otherwise, this method in redraw CustomListView abnormal happens * */ public void notifyDataSetChanged(){ CustomListView.setAddChildType(true); notifyCustomListView(this.myCustomListView); } /** * Redraw the Custom controls for the first time, you should invoke this method * In order to ensure that each load data do not repeat to get rid of the * custom of the ListView all View objects * The following will be set up to monitor events as controls * First load regardless whether OnItemClickListener and OnItemLongClickListener is NULL, * they do not influence events Settings * * @param formateList */ public void notifyCustomListView(CustomListView formateList){ this.myCustomListView = formateList; myCustomListView.removeAllViews(); getAllViewAddSexangle(); setOnItemClickListener(listener); setOnItemLongClickListener(longListener); } /** * Set the click event of each View, external can realize the interface for your call * * @param listener */ public void setOnItemClickListener(final OnItemClickListener listener){ this.listener = listener; for(int i = 0; i < myCustomListView.getChildCount(); i++){ final int parame = i; View view = myCustomListView.getChildAt(i); view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.i(TAG, "当前Item的值 : "+parame); listener.onItemClick(null, v, parame, getCount()); } }); } } /** * Set each long press event, the View outside can realize the interface for your call * * @param listener */ public void setOnItemLongClickListener(final OnItemLongClickListener listener){ this.longListener = listener; for(int i = 0; i < myCustomListView.getChildCount(); i++){ final int parame = i; View view = myCustomListView.getChildAt(i); view.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { listener.onItemLongClick(null, v, parame, getCount()); return true; } }); } }}
CustomListView需要用到的适配器MainSexangleAdapter需要继承上面的CustomAdapter
1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
public class MainSexangleAdapter extends CustomAdapter { private List<String> list; private Context con; private LayoutInflater inflater; public MainSexangleAdapter(Context context, List<String> list) { this.con = context; this.list = list; inflater = LayoutInflater.from(con); } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder vh = null; if(convertView == null){ vh = new ViewHolder(); convertView = inflater.inflate(R.layout.auto_adapter, null); vh.tv = (TextView) convertView.findViewById(R.id.adapter_text); convertView.setTag(vh); }else{ vh = (ViewHolder) convertView.getTag(); } String str = list.get(position); vh.tv.setText(str); return convertView; } public class ViewHolder{ public TextView tv; }}
然后是两个接口OnItemClickListener
1234
public interface OnItemClickListener { public void onItemClick(AdapterView<?> arg0,View arg1,int arg2,long arg3);}
OnItemLongClickListener
1234
public interface OnItemLongClickListener { public boolean onItemLongClick(AdapterView<?> arg0, View arg1,int arg2, long arg3);}
以上为java代码
所需要的布局文件 只要一个放入CustomListView 的xml
和一个adapter的xml;可以自己去写。
在MainActivity中实现方法即可
1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435363738394041424344454647
public class AutoActivity extends Activity{ private String TAG = AutoActivity.class.getSimpleName(); private CustomListView lv; private List<String> list = null; private MainSexangleAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.auto); CustomListView lv = (CustomListView) findViewById(R.id.sexangleView); setData(); ShowSexangleListView(); } private void ShowSexangleListView(){ adapter = new MainSexangleAdapter(this, list); lv.setDividerHeight(10); lv.setDividerWidth(10); lv.setAdapter(adapter); lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { Toast.makeText(AutoActivity.this, "点击了 : "+arg2, 300).show(); } }); } private void setData(){ list = new ArrayList<String>(); list.add("Powerball"); list.add("Lil Kim Pregnant"); list.add("Nicki Minaj"); list.add("MTA"); list.add("House of Cards"); list.add("Valentine's Day"); }}
以上即能实现 所需要的自动换行效果
注意 :如果布局文件 对这个自定义布局做了padding或者marging的话 CustomListView 当中的 argRight需要相应的减去你得设置。不然会有偏差。自己debug可以测试出来的!
Pass:以上查阅了很多网上资料,可是效果都不是很理想,后面联系到http://blog.csdn.net/alovebtoc/article/details/17244111博客的博主,在他的帮助下实现了以上效果,再次非常感谢对方
0 0
- 自定义布局实现自动换行
- 自定义布局控件,实现lineaerlayout自动换行
- 仿淘宝,自定义ViewGroup实现自动换行布局
- 自定义自动换行的线性布局linearLayout
- 自定义自动换行布局控件,实现子控件宽度超出整行时自动换行。setMeasuredDimension的使用
- 自定义自动换行布局控件,实现子控件宽度超出整行时自动换行。setMeasuredDimension的使用
- android之自定义ViewGroup和自动换行的布局的实现
- android之自定义ViewGroup和自动换行的布局的实现
- android之自定义ViewGroup和自动换行的布局的实现
- android之自定义ViewGroup和自动换行的布局的实现
- android之自定义ViewGroup和自动换行的布局的实现
- android之自定义ViewGroup和自动换行的布局的实现
- android之自定义ViewGroup和自动换行的布局的实现
- android之自定义ViewGroup和自动换行的布局的实现
- android之自定义ViewGroup和自动换行的布局的实现
- Android自定义ViewGroup自动换行实现滑动任意布局及事件处理效果
- android之自定义ViewGroup和自动换行的布局的实现
- android之自定义ViewGroup和自动换行的布局的实现
- 树状数组&线段树&RMQ
- 关于Outlook Express里的.dbx的文件
- lr的并行化
- MD5加密
- android预置apk
- 自定义布局实现自动换行
- 驱动开发之 Windows驱动编程基础教程(1.1-1.3)
- 什么是java序列化,如何实现java序列化?
- 数组中出现次数超过一半的数字
- 解決 Ubuntu fd0 錯誤 /dev/fd0 floppy drive
- oracle调优之sql语句
- centos关机与重启命令详解
- Android Map Api 使用和开发(2) 定位我的位置、地图弹出泡泡、通过经纬度获取地址
- 技术点详解---IPSec VPN基本原理