android 瀑布流效果(仿蘑菇街)

首先我们还是来看一款示例:(蘑菇街)

看起来很像我们的gridview吧,不过又不像,因为item大小不固定的,看起来是不是别有一番风味,确实如此.就如我们的方角图形,斯通见惯后也就出现了圆角.下面我简单介绍下实现方法.
第一种:
我们在配置文件中定义好列数.如上图也就是3列.我们需要定义三个LinearLayout,然后把获取到的图片add里面就ok了.

main.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="@android:color/background_light" 
    android:orientation="vertical" > 
 
    <include 
        android:id="@+id/progressbar" 
        layout="@layout/loading" /> 
 
    <com.jj.waterfall.LazyScrollView 
        android:id="@+id/lazyscrollview" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:layout_weight="1" 
        android:scrollbars="@null" > 
 
        <LinearLayout 
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent" 
            android:background="@android:color/background_light" 
            android:orientation="horizontal" 
            android:padding="2dp" > 
 
            <LinearLayout 
                android:id="@+id/layout01" 
                android:layout_width="fill_parent" 
                android:layout_height="fill_parent" 
                android:layout_weight="1" 
                android:orientation="vertical" > 
            </LinearLayout> 
 
            <LinearLayout 
                android:id="@+id/layout02" 
                android:layout_width="fill_parent" 
                android:layout_height="fill_parent" 
                android:layout_weight="1" 
                android:orientation="vertical" > 
            </LinearLayout> 
 
            <LinearLayout 
                android:id="@+id/layout03" 
                android:layout_width="fill_parent" 
                android:layout_height="fill_parent" 
                android:layout_weight="1" 
                android:orientation="vertical" > 
            </LinearLayout> 
        </LinearLayout> 
    </com.jj.waterfall.LazyScrollView> 
 
    <TextView 
        android:id="@+id/loadtext" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:background="@drawable/loading_bg" 
        android:gravity="center" 
        android:padding="10dp" 
        android:text="Loading..." 
        android:textColor="@android:color/background_dark" /> 
 
</LinearLayout> 

在这里因为图片很多就把图片放在assets文件中,如果想从网上拉取数据,自己写额外部分.

@Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        InitView(); 
 
        assetManager = this.getAssets(); 
        // 获取显示图片宽度 
        Image_width = (getWindowManager().getDefaultDisplay().getWidth() - 4) / 3; 
        try { 
            image_filenames = Arrays.asList(assetManager.list("images"));// 获取图片名称 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } 
 
        addImage(current_page, count); 
 
    } 
[java] 
/***
     * 加载更多
     * 
     * @param current_page
     *            当前页数
     * @param count
     *            每页显示个数
     */ 
    private void addImage(int current_page, int count) { 
        for (int x = current_page * count; x < (current_page + 1) * count 
                && x < image_filenames.size(); x++) { 
            addBitMapToImage(image_filenames.get(x), y, x); 
            y++; 
            if (y >= 3) 
                y = 0; 
        } 
 
    } 

 

[java] 
/***
     * 添加imageview 到layout
     * 
     * @param imagePath 图片name
     * @param j 列
     * @param i 行
     */ 
    public void addBitMapToImage(String imagePath, int j, int i) { 
        ImageView imageView = getImageview(); 
        asyncTask = new ImageDownLoadAsyncTask(this, imagePath, imageView, 
                Image_width); 
        asyncTask.setProgressbar(progressbar); 
        asyncTask.setLoadtext(loadtext); 
        asyncTask.execute(); 
 
        imageView.setTag(i); 
        if (j == 0) { 
            layout01.addView(imageView); 
        } else if (j == 1) { 
            layout02.addView(imageView); 
        } else if (j == 2) { 
            layout03.addView(imageView); 
        } 
 
        imageView.setOnClickListener(new OnClickListener() { 
 
            @Override 
            public void onClick(View v) { 
                Toast.makeText(MainActivity.this, 
                        "您点击了" + v.getTag() + "个Item", Toast.LENGTH_SHORT) 
                        .show(); 
 
            } 
        }); 
    } 

注释已经很明确,相信大家都看的明白,我就不过多解释了.
因为瀑布流不是一个规则的试图,所以我们不可能用listview那种“底部加一个按钮试图,点击加载更多,这样看起来很难看”。因此我们最好滑动到低端自动加载.
我们这里用到的自定义ScrollView,因为我们要实现下滑分页,这里要判断是否要进行分页等操作.
LazyScrollView.java (这个法很实用哦.)

[java] 
/***
 * 自定义ScrollView
 * 
 * @author zhangjia
 * 
 */ 
public class LazyScrollView extends ScrollView { 
    private static final String tag = "LazyScrollView"; 
    private Handler handler; 
    private View view; 
 
    public LazyScrollView(Context context) { 
        super(context); 
    } 
 
    public LazyScrollView(Context context, AttributeSet attrs) { 
        super(context, attrs); 
    } 
 
    public LazyScrollView(Context context, AttributeSet attrs, int defStyle) { 
        super(context, attrs, defStyle); 
    } 
 
    // 这个获得总的高度 
    public int computeVerticalScrollRange() { 
        return super.computeHorizontalScrollRange(); 
    } 
 
    public int computeVerticalScrollOffset() { 
        return super.computeVerticalScrollOffset(); 
    } 
 
    /***
     * 初始化
     */ 
    private void init() { 
 
        this.setOnTouchListener(onTouchListener); 
        handler = new Handler() { 
            @Override 
            public void handleMessage(Message msg) { 
                // process incoming messages here 
                super.handleMessage(msg); 
                switch (msg.what) { 
                case 1: 
                    if (view.getMeasuredHeight() <= getScrollY() + getHeight()) { 
                        if (onScrollListener != null) { 
                            onScrollListener.onBottom(); 
                        } 
 
                    } else if (getScrollY() == 0) { 
                        if (onScrollListener != null) { 
                            onScrollListener.onTop(); 
                        } 
                    } else { 
                        if (onScrollListener != null) { 
                            onScrollListener.onScroll(); 
                        } 
                    } 
                    break; 
                default: 
                    break; 
                } 
            } 
        }; 
 
    } 
 
    OnTouchListener onTouchListener = new OnTouchListener() { 
 
        @Override 
        public boolean onTouch(View v, MotionEvent event) { 
            // TODO Auto-generated method stub 
            switch (event.getAction()) { 
            case MotionEvent.ACTION_DOWN: 
                break; 
            case MotionEvent.ACTION_UP: 
                if (view != null && onScrollListener != null) { 
                    handler.sendMessageDelayed(handler.obtainMessage(1), 200); 
                } 
                break; 
 
            default: 
                break; 
            } 
            return false; 
        } 
 
    }; 
 
    /**
     * 获得参考的View,主要是为了获得它的MeasuredHeight,然后和滚动条的ScrollY+getHeight作比较。
     */ 
    public void getView() { 
        this.view = getChildAt(0); 
        if (view != null) { 
            init(); 
        } 
    } 
 
    /**
     * 定义接口
     * 
     * @author admin
     * 
     */ 
    public interface OnScrollListener { 
        void onBottom(); 
 
        void onTop(); 
 
        void onScroll(); 
    } 
 
    private OnScrollListener onScrollListener; 
 
    public void setOnScrollListener(OnScrollListener onScrollListener) { 
        this.onScrollListener = onScrollListener; 
    } 

我们还需要一个类,异步加载实现,我想有开发经验的朋友一定用过好多次了,这里就不展示代码了,想看的朋友,可以点击 下载 (如果认为还不错的话,请您一定要表示一下哦.)
对了,忘记一点,我们还需要对MainActivity 中的lazyScrollView实现OnScrollListener接口,对滑动到底部进行监听.

下面我介绍另外一种做法:(相对上面更灵活)
我们动态添加列.
配置文件就不贴了,和上面那例子一样,只不过里面值包含一个LinearLayout布局.
在这里我们动态添加列布局.

[java] 
     * init view
     */ 
    public void initView() { 
        setContentView(R.layout.main); 
        lazyScrollView = (LazyScrollView) findViewById(R.id.waterfall_scroll); 
        lazyScrollView.getView(); 
        lazyScrollView.setOnScrollListener(this); 
        waterfall_container = (LinearLayout) findViewById(R.id.waterfall_container); 
        progressbar = (LinearLayout) findViewById(R.id.progressbar); 
        loadtext = (TextView) findViewById(R.id.loadtext); 
 
        item_width = getWindowManager().getDefaultDisplay().getWidth() / column; 
        linearLayouts = new ArrayList<LinearLayout>(); 
 
        // 添加列到waterfall_container 
        for (int i = 0; i < column; i++) { 
            LinearLayout layout = new LinearLayout(this); 
            LinearLayout.LayoutParams itemParam = new LinearLayout.LayoutParams( 
                    item_width, LayoutParams.WRAP_CONTENT); 
            layout.setOrientation(LinearLayout.VERTICAL); 
            layout.setLayoutParams(itemParam); 
            linearLayouts.add(layout); 
            waterfall_container.addView(layout); 
        } 
 
    } 
[java]
/***
     * 获取imageview
     * 
     * @param imageName
     * @return
     */ 
    public ImageView getImageview(String imageName) { 
        BitmapFactory.Options options = getBitmapBounds(imageName); 
        // 创建显示图片的对象 
        ImageView imageView = new ImageView(this); 
        LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, 
                LayoutParams.FILL_PARENT); 
        imageView.setLayoutParams(layoutParams); 
        // 
        imageView.setMinimumHeight(options.outHeight); 
        imageView.setMinimumWidth(options.outWidth); 
        imageView.setPadding(2, 0, 2, 2); 
        imageView.setBackgroundResource(R.drawable.image_border); 
        if (options != null) 
            options = null; 
        return imageView; 
    } 
 
    /***
     * 
     * 获取相应图片的 BitmapFactory.Options
     */ 
    public BitmapFactory.Options getBitmapBounds(String imageName) { 
        int h, w; 
        BitmapFactory.Options options = new BitmapFactory.Options(); 
        options.inJustDecodeBounds = true;// 只返回bitmap的大小,可以减少内存使用,防止OOM. 
        InputStream is = null; 
        try { 
            is = assetManager.open(file + "/" + imageName); 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } 
        BitmapFactory.decodeStream(is, null, options); 
        return options; 
 
    } 

在这里我稍微修改了下,为要显示的iamgeview添加一个边框,这样看起来效果不错,我们动态滑动的同时, 然后图片陆续的填充边框.蘑菇街就是这种效果哦.


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值