android開發實現微博正文效果、頂部懸浮、ScrollView巢狀ListView
阿新 • • 發佈:2018-12-27
先來看一下效果圖
從圖中不難看出,我這裡使用了ScrollView巢狀ListView的方式來實現的這種效果。
這裡我們需要重寫一下ScrollView,程式碼如下:
package com.gsssk.ddpolice.myview;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;
/**
* Created by Administrator on 2016/6/15.
*/
public class MyScrollView extends ScrollView {
//回撥介面的物件
private OnScrollListener onScrollListener;
public MyScrollView(Context context) {
super(context);
}
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyScrollView (Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(ev);
}
/**在滑動的時候呼叫我們自己寫的回撥方法,來獲取滑動距離*/
@Override
protected void onScrollChanged (int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if(onScrollListener!=null){
onScrollListener.onScroll(t);
}
}
/**滑動回撥監聽的介面*/
public interface OnScrollListener{
/**回撥方法,返回MyScrollView在Y軸方向的滑動距離*/
public void onScroll(int scrollY);
}
public OnScrollListener getOnScrollListener() {
return onScrollListener;
public void setOnScrollListener(OnScrollListener onScrollListener) {
this.onScrollListener = onScrollListener;
}
}
這裡MyScrollView繼承了ScrollView,並重寫了onScrollChanged()方法,這個方法在ScrollView滑動的過程中不斷被呼叫,通過我們寫的介面中的回撥方法來獲取滑動的距離。
int ViewGroupTop;
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
////獲得ll_ViewGroup1_LRDA的頂部
viewGroupTop = ll_Location1_LifeRewardDetail.getBottom();
}
}
如圖評論和分享的所在的LinearLayout,通過這個方法來得到它的頂部位置。
在下面的java程式碼中評論和分享的所在的LinearLayout的id=ll_Top_LifeRewardDetail
評論和分享的所在的LinearLayout的父佈局叫ll_ViewGroup2_LRDA也是一個LinearLayout。
想實現懸浮效果在頂部需要給它留一個父佈局LinearLayout,
id=ll_ViewGroup2_LRDA。平常的時候他是隱藏的,需要的時候他是顯現的。
msv_ScrollView_LRDA.setOnScrollListener(this);
//監聽滾動Y值變化,通過addView和removeView來實現懸停效果
@Override
public void onScroll(int scrollY) {
//如果滑動的距離大於分享評論所在的位置
if (scrollY >= viewGroupTop) {
//如果分享評論不在頂部的父佈局中
if (ll_Top_LifeRewardDetail.getParent() != ll_ViewGroup2_LRDA) {
//讓頂部父佈局顯示出來
ll_ViewGroup2_LRDA.setVisibility(View.VISIBLE);
//讓listView獲得焦點
lv_Share_LifeRewardDetail.setFocusable(true);
lv_Comment_LifeRewardDetail.setFocusable(true);
//把分享和評論從原始的父佈局中移除
ll_ViewGroup1_LRDA.removeView(ll_Top_LifeRewardDetail);
//把分享評論加入頂部的佈局中
ll_ViewGroup2_LRDA.addView(ll_Top_LifeRewardDetail);
}
} //如果滑動距離小於分享評論所在的位置
else if (ll_Top_LifeRewardDetail.getParent() != ll_ViewGroup1_LRDA) {
ll_ViewGroup2_LRDA.setVisibility(View.GONE);
lv_Share_LifeRewardDetail.setFocusable(false);
lv_Comment_LifeRewardDetail.setFocusable(false);
ll_ViewGroup2_LRDA.removeView(ll_Top_LifeRewardDetail);
ll_ViewGroup1_LRDA.addView(ll_Top_LifeRewardDetail);
}
}
通過上述程式碼可以看出,實現頂部懸浮效果分為四部步:
1.確定要懸浮的佈局(這裡是分享評論)、給懸浮佈局一個不在懸浮狀態時的父佈局、給懸浮佈局一個頂部懸浮時的父佈局。
2.確定分享評論佈局的頂部位置(要懸浮的佈局)
3.獲取ScrollView滑動的距離。
4.通過滑動距離與分享評論頂部位置的比較,來進行往父佈局中移除新增的操作(要先移除在新增)。
這樣就實現了懸浮的效果,但是通常在ScrollView中使用ListView就會出現ListView只顯示一行的問題。通過下面方法可以給ListView一個剛好顯示全部內容的高度。
public class Utility {
public static void setListViewHeightBasedOnChildren(ListView listView) {
//獲取ListView的Adapter
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
//獲取ListView所以Item高度之和。
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
// listView.getDividerHeight()獲取子項間分隔符佔用的高度
// params.height最後得到整個ListView完整顯示需要的高度
listView.setLayoutParams(params);
}
}
然後在呼叫這個方法,引數是相應的ListView物件
ScrollViewSetListViewHeight.setListViewHeightBasedOnChildren(lv_Share_LifeRewardDetail);