自定义布局实现自动换行

来源:互联网 发布:智能小车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
原创粉丝点击