概述:
在开发中遇到了一个要求实现一个界面中展示列表数据,实现一个listview顶部悬停效果。找了一些
scrollview中嵌套listview的实现方式,但是后来感觉还是不如直接一个listview去实现,调试的时候没有那么头疼了。
下面图展示的是下拉一段具体半透明,在顶部是全透明
悬浮的那个图没截。。 下面白色的会有图,懒。没找
大概思路:
就是在listview中添加头部和底部去实现具体的逻辑,添加了两个头部。1:listview上部想展示的内容。2:悬停控件的内容
添加listview底部,也就是listview下方想添加的内容,一般在固定展示数据时添加一个加载更多并跳转到其他页面;
悬停的具体实现其实也就是在整体布局中添加一个悬停控件并隐藏,并在listview第二个头部到达顶部的时候去隐藏第二个悬停控件。反之,第二个头部离开顶部的时候显示。
下面贴出代码
activity布局 activity_secondhand 在这里设置要停留的搜索框和悬停的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical"
android:gravity="center_horizontal"
>
<FrameLayout
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listviewz"
android:scrollbars="none"
android:fadingEdge="none"
android:overScrollMode="never"
android:cacheColorHint="#00000000"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
<LinearLayout
android:id="@+id/linzzz"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<LinearLayout
android:padding="16dp"
android:id="@+id/re"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:id="@+id/ll_search"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="33dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="16dp"
android:background="@drawable/edit_bg"//这里是一个自定义的边框背景,可以自行搜索
android:gravity="center"
android:orientation="horizontal">
<View
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:background="@color/line" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:src="@drawable/ic_search" />
<TextView
android:id="@+id/et_key"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@null"
android:maxLines="1"
android:padding="5dp"
android:textColor="@color/black" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/invis"
android:layout_width="match_parent"
android:layout_height="30dp">
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="悬浮"
android:maxLines="1"
/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</FrameLayout>
</RelativeLayout>
xml布局 menu_layout 这里放置要悬浮部分上面部分的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center"
android:src="@drawable/s6" />//随意放一张图片
</LinearLayout>
</LinearLayout>
xml布局 xuanfu悬浮停留的布局 要和activity 布局中的悬浮部分一样,这样才能隐藏显示的不自然一些
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="30dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp">
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="悬浮"
android:maxLines="1"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
以下是activity中调用的代码
ListView lv;
int height;
lv=findViewById(R.id.listviewz);//
View menu=View.inflate(this, R.layout.menu_layout, null);
View xuanfu=View.inflate(this, R.layout.xuanfu, null);
lv.addHeaderView(menu);
lv.addHeaderView(xuanfu);
lv.setAdapter(ada);//根据不同的需求添加所需要的适配器
LinearLayout re=findViewById(R.id.re);
LinearLayout invis=findViewById(R.id.invis);
lv.setOnScrollListener(new OnScrollListener() {
private SparseArray recordSp = new SparseArray(0);
private int mCurrentfirstVisibleItem = 0;
int alpha = 0;
int count = 0;
float scale = 0;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState){
case AbsListView.OnScrollListener.SCROLL_STATE_IDLE://停止滚动
{
ada.setScrollState(true);
break;
}
case AbsListView.OnScrollListener.SCROLL_STATE_FLING://滚动做出了抛的动作
{
//设置为正在滚动
ada.setScrollState(false);
break;
}
case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL://正在滚动
{
//设置为正在滚动
ada.setScrollState(false);
break;
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {
mCurrentfirstVisibleItem = firstVisibleItem;
View firstView = view.getChildAt(0);
if (null != firstView) {
ItemRecod itemRecord = (ItemRecod) recordSp.get(firstVisibleItem);
if (null == itemRecord) {
itemRecord = new ItemRecod();
}
itemRecord.height = firstView.getHeight();
itemRecord.top = firstView.getTop();
recordSp.append(firstVisibleItem, itemRecord);
int h = getScrollY();//滚动距离
//顶部透明,也可以通过最后的方法拿到一个view的高度,跟需求去做
if(h<=300){
scale = (float) h / 300;
alpha = (int) (255 * scale);
// 随着滑动距离改变透明度s
// Log.e("al=","="+alpha);
// tv_titiys.setText("111");
// iv_back.setAlpha(255);
// tv_titiys.setTextColor(Color.argb(255, 0, 0, 0)); //文字透明度
// tv_titiys.getBackground().mutate().setAlpha(0);
re.getBackground().mutate().setAlpha(alpha);
}else{
if (alpha < 255) {
// Log.e("执行次数", "=" + (++count));
// 防止频繁重复设置相同的值影响性能
alpha = 255;
re.getBackground().mutate().setAlpha(255);
// iv_back.getBackground().mutate().setAlpha(255);
// re.setBackgroundColor(Color.argb(alpha, 255, 0, 0));
}
}
//顶部悬停
if(h>=height){
invis.setVisibility(View.VISIBLE);
}else{
invis.setVisibility(View.GONE);
}
}
}
private int getScrollY() {
int height = 0;
for (int i = 0; i < mCurrentfirstVisibleItem; i++) {
ItemRecod itemRecod = (ItemRecod) recordSp.get(i);
if(itemRecod != null){
height += itemRecod.height;
}
}
ItemRecod itemRecod = (ItemRecod) recordSp.get(mCurrentfirstVisibleItem);
if (null == itemRecod) {
itemRecod = new ItemRecod();
}
return height - itemRecod.top;
}
class ItemRecod {
int height = 0;
int top = 0; }
});
height的值可以通过以下方法去实现去计算出一个view高度
int w = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
re.measure(w, h);
int height1 = re.getMeasuredHeight();
int w1 = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
int h1 = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
menu.measure(w1, h1);
int height2= menu.getMeasuredHeight();
height=height2-height1;