• 【Android-view】listView 每个item里动态添加不定量的控件,Android 自动换行


    问题描述:

      开发过程中,遇到了在listview里面的每个item都有可能显示图片,并且需要显示的图片的数量不确定,需要自动换行。

    如图:第一行显示三张图片,第二行显示四张图片。数量0---正无穷(内存支持的情况下)

    解决办法:

      最初就是直接从网上找Android自动换行的控件,再此感谢eoe论坛里**dahege **分享的源码。

      dahege eoe论坛原文地址:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=195276

      但是我直接拿来用的时候出现了个问题,就是当有四张图片的时候只显示三行。

      具体解决办法如下:

      a.修改values下attrs.xml文件

        增加一个每行显示多少列的属性,类似gridview 

     1 <resources>
     2     <declare-styleable name="FlowLayout">
     3         <attr name="horizontalSpacing" format="dimension" />
     4         <attr name="verticalSpacing" format="dimension" />
     5         <attr name="numColumns" format="integer" /><!--这个属性为新加的-->
     6     </declare-styleable>
     7     <declare-styleable name="FlowLayout_LayoutParams">
     8         <attr name="layout_breakLine" format="boolean" />
     9         <attr name="layout_horizontalSpacing" format="dimension" />
    10     </declare-styleable>
    11 </resources>

      b.修改FlowLayout.java 源文件

        1.在构造方法里得到用户在cml文件里设置的numColumns

        public FlowLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FlowLayout);
            try {
                mHorizontalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_horizontalSpacing, 0);
                mVerticalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_verticalSpacing, 0);
                numColumns = a.getInt(R.styleable.FlowLayout_numColumns, 3);//得到用户在布局文件中设置的没行显示的列数
            } finally {
                a.recycle();
            }
            
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setColor(0xffff0000);
            mPaint.setStrokeWidth(2.0f);
        }

        2.修改onMeasure方法,由于对这块还不太了解,所以只是简单的改了一下,测试之后效果是实现了,暂未发现其他问题。应该还有更好的解决方案,希望有人指正。

     1 @Override
     2     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     3         int widthSize = MeasureSpec.getSize(widthMeasureSpec) - getPaddingRight();
     4         int widthMode = MeasureSpec.getMode(widthMeasureSpec);
     5         boolean growHeight = widthMode != MeasureSpec.UNSPECIFIED;
     6 
     7         int width = 0;
     8         int height = getPaddingTop();
     9 
    10         int currentWidth = getPaddingLeft(); 
    11         int currentHeight = 0;               
    12 
    13         boolean breakLine = false;
    14         boolean newLine = false;
    15         int spacing = 0;
    16 
    17         final int count = getChildCount();
    18         for (int i = 0; i < count; i++) {
    19             View child = getChildAt(i);
    20             measureChild(child, widthMeasureSpec, heightMeasureSpec);
    21 
    22             LayoutParams lp = (LayoutParams) child.getLayoutParams();
    23             spacing = mHorizontalSpacing;
    24             if (lp.horizontalSpacing >= 0) {
    25                 spacing = lp.horizontalSpacing;
    26             }
    27 
    28             if (growHeight && (i == numColumns||breakLine || currentWidth + child.getMeasuredWidth() > widthSize)) {
    29 //                newLine = true;
    30                 
    31                 height += currentHeight + mVerticalSpacing;
    32                 width = Math.max(width, currentWidth - spacing);
    33                 
    34                 currentHeight = 0;
    35                 currentWidth = getPaddingLeft();
    36                 
    37             }
    38 //            else {
    39 //                newLine = false;
    40 //            }
    41             if (i>numColumns&&i%numColumns==0) {//主要修改的是这个判断语句,原版的判断语句是29,38,39,40行的被隐掉的。我自己用原版的判断语句有问题,
    42                 newLine = false;
    43             }
    44 
    45             lp.x = currentWidth;
    46             lp.y = height;
    47 
    48             currentWidth += child.getMeasuredWidth() + spacing;
    49             currentHeight = Math.max(currentHeight, child.getMeasuredHeight());
    50             
    51             breakLine = lp.breakLine;
    52         }
    53 
    54         if (!newLine) {
    55             height += currentHeight;
    56             width = Math.max(width, currentWidth - spacing);
    57         }
    58 
    59         width += getPaddingRight();
    60         height += getPaddingBottom();
    61 
    62         setMeasuredDimension(resolveSize(width, widthMeasureSpec),
    63                 resolveSize(height, heightMeasureSpec));
    64     }

    至此,就修改完毕了。

    具体使用办法如下。

    a.在listview的item布局文件中使用framelayout自定义控件

    1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     xmlns:f="http://schemas.android.com/apk/res/你的androidmanifest.xml文件中的package属性值"
     4     android:layout_width="fill_parent"
     5     android:layout_height="wrap_content"
     6      >
     7 
     8    
     9         <com.xingyunhudong.view.FlowLayout
    10             android:id="@+id/flowlaytou"
    11             android:layout_width="fill_parent"
    12             android:layout_height="wrap_content"
    13             android:layout_marginTop="8dp"
               f:numColumns="3"<!--也可以不指定,如果不指定,在FrameLayout的构造函数里,默认取值为3列-->
    
    14              >
    15         </com.xingyunhudong.view.FlowLayout>
    16 
    17         
    18 
    19 </LinearLayout>

    b.在adapter中设值

    public class XXXAdapterextends BaseAdapter {
    
        private LayoutInflater inflater;
        private List<XXX> xxxList;
        private Context context;
    
        private ViewGroup.LayoutParams paramsImg, paramsVideo;
        private int sw;
    
        public HuaTiAdapter(Context context, List<xxx> xxxList) {
            this.xxxList = xxxList;
            this.context = context;
            inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            sw = CommonUtils.getScreenWidth((Activity) context);
            int w = context.getResources().getDimensionPixelSize(
                    R.dimen.xxx_img_total_width);
            sw = sw - w;
            paramsImg = new ViewGroup.LayoutParams(sw / 3, sw / 3);
            paramsVideo = new ViewGroup.LayoutParams(sw, 0);//为了图片适配
        }
    
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return xxxList.size();
        }
    
        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return xxxList.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }
    
        class ViewHolder {
            FlowLayout ll;
            int flag;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            ViewHolder holder = null;
            xxxBean huati = xxxList.get(position);
            if (convertView == null
                    || ((ViewHolder) convertView.getTag()).flag != position) {//第一个判断是优化listview加载速度及内存消耗,第二个判断是为了防止图片错位
                holder = new ViewHolder();
                holder.flag = position;
                convertView = inflater.inflate(R.layout.xxx_item_layout, null);
                
                holder.ll = (FlowLayout) convertView.findViewById(R.id.flowlaytou);
                ImageBean video = xxx.getVideoImg();
                if (video != null && video.getUrl() != null
                        && !"".equals(video.getUrl().trim())) {
                    paramsVideo.height = video.getHeight() * sw / video.getWidth();
                    addVideoView(holder.ll, video.getUrl(), paramsVideo, inflater);
                }
                List<ImageBean> imgList = huati.getImgList();
                if (imgList != null && imgList.size() > 0) {
                    for (int i = 0; i < imgList.size(); i++) {
                        addImageView(holder.ll, imgList.get(i).getUrl(), paramsImg,
                                inflater, imgList, i);
                    }
                }
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
    
            return convertView;
        }
    
        private void addVideoView(FlowLayout ll, final String url,
                LayoutParams params, LayoutInflater inflater) {
            ImageView v = (ImageView) inflater.inflate(
                    R.layout.yyy_image_layout, null);//这个layout里面就只有一个imageview空间,特别简单
            v.setLayoutParams(params);
            ImageUtil.display(url, v);
            v.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    //这里的点击事件也完全没有问题,不会错位,不会点击失效
                }
            });
            ll.addView(v);
    
        }
    
        private void addImageView(FlowLayout ll, String url, LayoutParams params,
                LayoutInflater inflater) {
            // TODO Auto-generated method stub
            ImageView v = (ImageView) inflater.inflate(
                    R.layout.weixiu_image_layout, null);
            v.setLayoutParams(params);
            ImageUtil.display(url, v);
            v.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    //这里的点击事件也完全没有问题,不会错位,不会点击失效
     } }); ll.addView(v); } }

    至此,就就结束了,希望可以帮到一部分人。

  • 相关阅读:
    索引总结篇
    数据库的安全管理
    数据库备份对日志文件的影响
    数据文件与日志文件读取机制
    更新操作所带来的影响
    页拆分-产生碎片
    你不可不知的T-SQL执行顺序
    实用T-SQL收集
    Left Join的神奇效果
    我对数据库索引的理解
  • 原文地址:https://www.cnblogs.com/MrZz/p/3655585.html
Copyright © 2020-2023  润新知