android实现瀑布流
㈠ 求教 android瀑布流该如何实现
网上关于android瀑布流的例子一大堆,但是很多都是很复杂,对于新手来说有一定的难度。
原理很简单,就是异步下载图片,把图片addView到ScrollView(因为可以上下一直拖动)中,你需要屏幕显示几列就在ScrollView中放置几个LinearLayout,
下面我就一个简单的例子来讲解android瀑布流的用法,样子很丑就不上图了。。
1、在xml布局文件:很简单就是
2、在java代码中:
先声明几个变量,其中imagePathStr数组用来存图片的链接
private LinearLayout leftLayout;
private LinearLayout rightLayout;
private String[] imagePathStr = { "http://www.cf69.com/Upfiles/BeyondPic/2010-08/20108175740983313.jpg",
"http://www.syfff.com/UploadFile/pic/2008122163204.jpg", "http://pic.newssc.org/0/10/34/32/10343297_564251.jpg",
"http://ent.hangzhou.com.cn/images/20090311/zym2009031323.jpg", "http://a4.att.hudong.com/86/60/01300000013093119087608457965.jpg",
"http://file.sdteacher.gov.cn/upload/gz0901/images/0907/22/110437191.jpg",
"http://www.fun9.cn/uploadfile/starpic/uploadpics/200910/20091008090155126.jpg",
"http://img3.yxlady.com/yl/UploadFiles_5361/20110820/20110820120609469.jpg",
其次,在oncreate()中采用异步加载图片的方法把获取到的Drawable添加到左右两栏的LinearLayout中:
㈡ 1.Android recycleView万能分隔线 GridLayoutManager布局item左右间距均等(最易懂)
今天开始讲RecycleView的系列教程。分割线,分组,局部刷新,动态添加,缓存原理,抖音效果,瀑布流。嵌套,动画等等
RecyclerView的分割线是通过canvas和设置item偏移画出来的.需要知道2个方法
getItemOffsets()和onDraw方法
getItemOffsets 是针对每一个 ItemView
onDraw:遍历,进行颜色修改
我们可以看到自定义的 TestDividerItemDeoration 只实现了一个方法 getItemOffsets()。方法里面有四个参数。
Rect outRect
View view
RecyclerView parent
RecyclerView.State state
绿色区域代表 RecyclerView 中的一个 ItemView,而外面橙色区域也就是相应的 outRect,也就是 ItemView 与其它组件的偏移区域,等同于 margin 属性,通过复写 getItemOffsets() 方法,然后指定 outRect 中的 top、left、right、bottom 就可以控制各个方向的间隔了。
这实现了简单的分隔线效果,但这种方法分隔线的效果只能取决于背景色,如果我要定制分割线的颜色呢?这个时候就要 onDraw()。
————————————————
源码分析:在recycleview中的
分割线要注意,没有颜色,默认是白色的,会看不出来
第一种方案,通过
getItemOffsets()方法进行分割线!
判断是否是第一个,最后一个,是单个还是双个,是什么类型
/***
* 分割线要注意,没有颜色,默认是白色的,会看不出来
* @param outRect
* @param view
* @param parent
* @param state
*/
private void testItemOffset(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int childAdapterPosition = parent.getChildAdapterPosition(view);
if (childAdapterPosition ==0) {
outRect.set(0, 20, 0, 20);
}else {
outRect.set(0, 0, 0, 20);
}
}
第二种方案:ondraw()
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
int childCount = parent.getChildCount();
for (int i =0; i < childCount; i++) {
View view = parent.getChildAt(i);
int index = parent.getChildAdapterPosition(view);
//第一个ItemView不需要绘制
if (index ==0) {
continue;
}
float dividerTop = view.getTop() -mDividerHeight;
float dividerLeft = parent.getPaddingLeft();
float dividerBottom = view.getTop();
float dividerRight = parent.getWidth() - parent.getPaddingRight();
c.drawRect(dividerLeft, dividerTop, dividerRight, dividerBottom, mPaint);
}
}
GridLayoutManager布局item左右间距均等
思路分析
首先,我们知道,对于 GridLayoutmanager ,当我们设置的 spancount 为 3 的时候,那么每个 item 的最大宽度为 itemMaxW = recycylerW / spancount = recycylerW / 3.
假设我们 spancount 为 3,那么在不设置 itemDercation 的情况下它的分布是这样的,可以看到第一列与最后一行的距离是不一样的
GridVIew出现的问题:本来固定item.高度和宽度
1.分割线有,不是理想的,左右均等
2.上下没有分割线
源码得到:
按上面分析的源码,我们可以知道,调用outRect.set(int left, int top, int right, int bottom)方法时,left一直为0,right一直为divider的宽度,而每一项item的宽度都要减去(left+right)大小,
left一直为0,right一直为divider的宽度
左上右下到底是什么的值?
计算每一个item移动的距离,左边和右边的移动距离
计算分析:
1.左边的分割线宽度为sW (已知)
2.每个显示item的宽度,布局定义的itemWidth
3. 总共分割线宽度:totalDivider=屏幕宽度-spanCount*itemWidth
4.列之间的分割线宽度为dw =(屏幕宽度-spanCount*item-2*sW )/(spantcount-1)
5.每个item需要留出的空间 ew=totalDivider/spanCount(即paddingLeft+paddingRight)
left: 左边的间距值(绝对值,差值)
right:右边的间距值
每个item移动的距离:
第一个Item:L0=sW R0=eW-sW
第二个Item:L1=dW-R0=dW-eW+sW R1=eW-L1=2eW-dW-sW
第三个Item:L2=dW-R1=2(dW-eW)+sW R2=eW-L2=3eW-2dW-sW
得出公式:
Ln=(position%spanCount)*(dw-ew)+sw
Rn=ew-Ln
总结:得到3个值dw,ew, sw的值
sw:左边的距离
ew:每个的平均的分割线
dw: 列之间的分割线宽度
int firstLastSpace =50;//最左边的分割线宽度
@SuppressLint("LongLogTag")
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
count++;
outRect.top =20;
mDividerHeight =0;
int itemWidth =dip2px(context, 100);
int screenWidth = getScreenWidth(context);
int dw = (screenWidth -3 * itemWidth -2 *firstLastSpace) /2;//最终计算出这个padding值
//误区:中间的分割线的总距离,左右可能是不等的
int totalDivder = screenWidth -3 * itemWidth;
Log.d("TestDividerItemDecoration", "totalDivder" + totalDivder);
int eachDivder = totalDivder /3;
int itemPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
//不要用for循环
outRect.left = (itemPosition %3) * (dw - eachDivder) +firstLastSpace;
outRect.right = eachDivder - outRect.right;
}
错误的思路:
//误区:中间的分割线的总距离,左右可能是不等的
//不要用for循环
int firstLastSpace =50;//最左边的分割线宽度
@SuppressLint("LongLogTag")
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
count++;
outRect.top =20;
mDividerHeight =0;
int itemWidth =dip2px(context, 100);
int screenWidth = getScreenWidth(context);
int padding = (screenWidth -3 * itemWidth -2 *firstLastSpace) /4;//最终计算出这个padding值
//不能这么算,必须保证每个item的分割线一样才行。
Log.d("TestDividerItemDecoration", "getItemOffsets" +count +"item宽度:" + itemWidth +"padding" + padding);
//仅仅计算左边和右边的距离
int childCount = parent.getChildCount();
for (int i =0; i < childCount; i++) {
if (i %3 ==0) {//最左边的item
outRect.left =firstLastSpace;
outRect.right = padding;
}else if (i %3 ==1) {
outRect.left = padding;
outRect.right = padding;
}else if (i %3 ==2) {
outRect.left = padding;
outRect.right =firstLastSpace;
}
}
}
瀑布流的设置:
int spanIndex = layoutParams.getSpanIndex();
public class FeedDecorationextends RecyclerView.ItemDecoration {
private ;
public FeedDecoration(HomePageCardAdapter mHomePageCardAdapter) {
this.mHomePageCardAdapter = mHomePageCardAdapter;
}
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
if (mHomePageCardAdapter ==null) {
return;
}
if (mHomePageCardAdapter.getItemViewType(parent.getChildAdapterPosition(view)) == HomePageMultipleCard.HOMEPAGE_MULTIPLE_CARD_TYPE_FITNESS_FEED) {
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
int spanIndex = layoutParams.getSpanIndex();
if (spanIndex ==0) {
outRect.set(DensityUtil.dip2px(ShadowApp.context(), 14), 0, DensityUtil.dip2px(ShadowApp.context(), 5), DensityUtil.dip2px(ShadowApp.context(), 10));
}else {
outRect.set(DensityUtil.dip2px(ShadowApp.context(), 5), 0, DensityUtil.dip2px(ShadowApp.context(), 14), DensityUtil.dip2px(ShadowApp.context(), 10));
}
}
}
}
demo地址: https://github.com/pengcaihua123456/shennanda
㈢ android 怎么实现 逆向瀑布流
android 实现逆向瀑布流
将实例化imageview往layout里面添加
通过linearlayout
三个流的瀑布代码:
㈣ Android之RecyclerView介绍
从Android 5.0开始,谷歌公司推出了一个用于大量数据展示的新控件RecylerView,可以用来代替传统的ListView,更加强大和灵活。
RecyclerView是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,这一点从它的名字Recyclerview即回收view也可以看出。
RecyclerView 支持 线性布局、网格布局、瀑布流布局 三种,而且同时还能够控制横向还是纵向滚动。
RecyclerView 基础使用关键点同样有两点:
另外,系统已经为我们提供了三个相关的实现类 LinearLayoutManager(线性布局效果)、GridLayoutManager(网格布局效果)、StaggeredGridLayoutManager(瀑布流布局效果)。
使用RecyclerView,当前版本需要直接在xml文件中定义:
效果图:
㈤ android瀑布流怎么显示
今天介绍一个瀑布流控件:PinterestLikeAdapterVie
使用方法类似于ListView,下面是我使用该控件实现一个显示系统图片的简单应用:
xml中:
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
>
<com.huewu.pla.lib.multicolumnlistview<p="">
xmlns:pla="http://schemas.android.com/apk/res-auto"
android:background="#000000"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
pla:plaColumnNumber="3"
pla:plaLandscapeColumnNumber="3"
>
plaColumnNumber表示显示多少列,plaLandscapeColumnNumber表示横屏下显示多少列。
但与StaggeredGridView不同的是他没有提供设置item之间间隙大小的属性,这个可以通过在item的xml中设置一个padding来解决。
㈥ 如何给recyclerView瀑布流设置均等间距
adapter里面计算宽高,这个宽高可以让服务器获取当让我们也可以自己获取。
下面就说下实现方式吧
既然要动态适配宽高就要根据图片的宽度和手机的宽度计算出比率来然后根据这个比率来计算imageview的高度
package com.jtech.scrollimageloaddemo;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.jtech.adapter.RecyclerAdapter;
import com.jtech.view.RecyclerHolder;
import java.util.ArrayList;
import java.util.List;
/**
* 图片适配器
* 关于 同等间距的recycleView
* 我们在xml文件里设置的距离是dp 在代码里设置的距离是px
* 所以都在代码中设置统一格式就是同等编剧的recyclerview
* Created by wuxuyang on 16/5/6.
*/
public class ImageAdapter extends RecyclerAdapter<ImageModel> {
private boolean isScroll = false;
private int itemWidth;
public ImageAdapter(Activity activity) {
super(activity);
//计算item的宽度
itemWidth = (DeviceUtils.getScreenWidth(activity)-48) / 2;
}
public void setScroll(boolean scroll) {
isScroll = scroll;
if (!isScroll) {
notifyDataSetChanged();
}
}
@Override
public View createView(LayoutInflater layoutInflater, ViewGroup viewGroup, int i) {
return layoutInflater.inflate(R.layout.view_item, viewGroup, false);
}
@Override
public void convert(RecyclerHolder recyclerHolder, ImageModel imageModel, int i) {
ImageView imageView = recyclerHolder.getView(R.id.imageview);
//等比缩放
double ratio = (itemWidth * 1.0) / imageModel.getWidth();
int height = (int) (imageModel.getHeight() * ratio);
ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams();
layoutParams.width = itemWidth;
layoutParams.height = height;
imageView.setLayoutParams(layoutParams);
//显示图片
// if (isScroll) {
// imageView.setImageResource(R.mipmap.ic_launcher);
// } else {
Glide.with(getActivity()).load(imageModel.getUrl()).placeholder(R.mipmap.ic_launcher).into(imageView);
// }
}
}
㈦ android瀑布流怎么实现点击监听
holder.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String webInfo = holder2.url2.getText().toString();
StaggeredAdapter里面的点击事件这样写,外面要用final定义,你直接findviewbyid,肯定只会找到第一个item的里面的textview的url2,所以不管点哪个都会显示第一个的,你这样写,不光瀑布流会这样,就算普通的listview也会这样。你这标题一个“瀑布流”估计很多人都不会来看是哪里错了,其实跟瀑布流一点关系没有
㈧ 像美丽说,蘑菇街瀑布流布局在Android中是怎么做的
那个是需要一个主题的,你可以在网上网络一下,搜索一下这主题。
㈨ android listview 每行中 有两列。 第二列有两行的效果是怎么做的 下图给图~
可以用“瀑布流”实现。
github上有很多:https://github.com/search?utf8=%E2%9C%93&q=android+waterfall&type=Repositories&ref=searchresults
㈩ android recyclerview到底提示
我也不知道你是什么意思。
RecyclerView是一个增强版的ListView,不仅可以轻松实现和ListView同样的效果,还优化了ListView存在的各种不足之处。可以使用RecyclerView实现纵向布局、横向布局、网格布局、瀑布流布局,其中瀑布流最为炫酷。