现在的位置: 首页 > 综合 > 正文

自定义布局实现自动换行

2014年09月05日 ⁄ 综合 ⁄ 共 9090字 ⁄ 字号 评论关闭

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
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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
 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
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

1
2
3
4
public interface OnItemClickListener {

    public void onItemClick(AdapterView<?> arg0,View arg1,int arg2,long arg3);
}

OnItemLongClickListener

1
2
3
4
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
 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
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博客的博主,在他的帮助下实现了以上效果,再次非常感谢对方

抱歉!评论已关闭.