Android中使用ScrollView指定view的頂部懸停效果
因項目中的需要實現(xiàn)ScrollView頂部的懸停,也不是太難便自己實現(xiàn)功能,話不多說,先上效果圖

紅色text一到頂上便會懸浮在上面,不會跟隨scrollview的滑動而上滑。
原理:
原理其實很簡單就是對view的gone和visible,寫兩個相同的要置頂?shù)膙iew,一個設(shè)置為gone,一個為visible,當可見的view超出屏幕范圍的時候,將不可以的view設(shè)置為visible,不可見的view 與scrollview要同級,這樣滑動的時候不會影響到view的位置。
直接上代碼
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.lanmai.ObservableScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 中間就是填充的view就不寫了-->
<!--指定要置頂?shù)膙iew-->
<TextView
android:id="@+id/specific_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/holo_red_dark"
android:gravity="center"
android:text="text"
android:textSize="40sp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@android:color/darker_gray"
android:gravity="center"
android:text="text"
android:textSize="40sp"/>
</LinearLayout>
</RelativeLayout>
</com.lanmai.ObservableScrollView>
<!--指定要置頂?shù)南嗤膙iew visibility設(shè)置為gone -->
<TextView
android:id="@+id/specific_text_view_gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/holo_red_dark"
android:gravity="center"
android:text="text"
android:textSize="40sp"
android:visibility="gone"/>
</RelativeLayout>
接下來要重寫scrollview,為什么要重寫ScrollView,scrollview的滑動監(jiān)聽事件setOnScrollChangeListener 這個方法是在6.0以上才能用的。為了考慮低版本的的需求,要重寫ScrollView把接口開放出來。
重寫ScrollView
public class ObservableScrollView extends ScrollView {
private ScrollViewListener scrollViewListener = null;
public ObservableScrollView(Context context) {
super(context);
}
public ObservableScrollView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public ObservableScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setScrollViewListener(ScrollViewListener scrollViewListener) {
this.scrollViewListener = scrollViewListener;
}
@Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
super.onScrollChanged(x, y, oldx, oldy);
if (scrollViewListener != null) {
scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
}
}
public interface ScrollViewListener {
void onScrollChanged(ScrollView scrollView, int x, int y, int oldx, int oldy);
}
}
我把重寫的ScrollView命名為ObservableScrollView,重寫三個構(gòu)造方法,都是換湯不換藥的作法,這里就不贅述。 最重要的是重寫onScrollChanged這個方法,如何把滑動監(jiān)聽事件開放出去呢,其實也就是寫一個監(jiān)聽回調(diào),參數(shù)和onScrollChanged里面的的參數(shù)一樣就可以了,當然主要不是用到這些參數(shù),只是為了判斷ScrollView的滑動事件,參數(shù)對于這個功并不是很重要。那這樣,一個簡單的自定義就寫好了scrollview
如何去用?
用法也是挺簡單的,直接上代碼
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scroll_view);
mTextView = ((TextView) findViewById(R.id.specific_text_view));
mScrollView = ((ObservableScrollView) findViewById(R.id.scrollview));
mVisibleTextView = ((TextView) findViewById(R.id.specific_text_view_gone));
mTextView.setOnClickListener(this);
mScrollView.setScrollViewListener(this);
}
這里onCreate方法里面的,也簡單,拿到view 并且設(shè)置監(jiān)聽事件,當然,這里多實現(xiàn)了一個點擊view置頂?shù)墓δ?,監(jiān)聽設(shè)置好以后,實現(xiàn)相應(yīng)的接,接下來就是重頭戲了
@Override
public void onScrollChanged(ScrollView scrollView, int x, int y, int oldx, int oldy) {
int[] location = new int[2];
mTextView.getLocationOnScreen(location);
int xPosition = location[0];
int yPosition = location[1];
Log.d("ScrollViewActivity", "yPosition:" + yPosition);
int statusBarHeight = getStatusBarHeight();
Log.d("ScrollViewActivity", "statusBarHeight:" + statusBarHeight);
if (yPosition <= statusBarHeight) {
mVisibleTextView.setVisibility(View.VISIBLE);
} else {
mVisibleTextView.setVisibility(View.GONE);
}
}
onScrollChanged這個方法就是自己寫的監(jiān)聽回調(diào),里面的參數(shù)就是Scrollview滑動的時候回調(diào)出來的,里面的參數(shù)并不用去關(guān)心
int[] location = new int[2];
mTextView.getLocationOnScreen(location);
int xPosition = location[0];
int yPosition = location[1];
/* mTextView就是要懸浮的view,getLocationOnScreen(location)這個方法就是拿到view在屏幕中的位置 ,傳入一個數(shù)組,最后得到的yPosition就是view在屏幕中的高度,這里面調(diào)用了native層的實現(xiàn)方式,所以數(shù)組能直接附上值*/
// 值得注意的是,拿到的這個高度還包括狀態(tài)欄的高度。只要減掉就可以了,狀態(tài)欄的高度獲取獲取附上代碼:
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
int statusBarHeight = getStatusBarHeight();
Log.d("ScrollViewActivity", "statusBarHeight:" + statusBarHeight);
通過獲取到的狀態(tài)欄高度,如果小于狀態(tài)欄的高度就表示已經(jīng)滑出屏幕了,將要置頂?shù)膙iew設(shè)置為visibvle否則設(shè)置為gone
if (yPosition <= statusBarHeight) {
mVisibleTextView.setVisibility(View.VISIBLE);
} else {
mVisibleTextView.setVisibility(View.GONE);
}
這樣scrollview的懸浮置頂?shù)墓δ芫蛯崿F(xiàn)了,這里我也給出點擊view置頂?shù)拇a
@Override
public void onClick(View v) {
int[] location = new int[2];
v.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
mScrollView.scrollBy(0, location[1] - getStatusBarHeight());
}
當然要緩慢的滑動過程用smoothScrollBy替代就可以了
結(jié)論:
實現(xiàn)這種效果,找對了思路就可以很容易的寫出來了,這是一種比較簡單的實現(xiàn)方式了,源碼我就不貼出來了,基本已經(jīng)都在了。
以上所述是小編給大家介紹的Android中使用ScrollView指定view的懸停效果,希望對大家有所幫助。。。
相關(guān)文章
Android開發(fā)之MediaPlayer多媒體(音頻,視頻)播放工具類
這篇文章主要介紹了Android開發(fā)之MediaPlayer多媒體(音頻,視頻)播放工具類,涉及Android針對音頻文件的讀取、播放、暫停、繼續(xù)等操作實現(xiàn)技巧,需要的朋友可以參考下2017-12-12
Android編程實現(xiàn)webview執(zhí)行l(wèi)oadUrl時隱藏鍵盤的workround效果
這篇文章主要介紹了Android編程實現(xiàn)webview執(zhí)行l(wèi)oadUrl時隱藏鍵盤的workround效果,較為詳細的分析了執(zhí)行l(wèi)oadUrl時隱藏鍵盤的workround具體步驟與兩種實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-10-10
RecyclerView使用payload實現(xiàn)局部刷新
這篇文章主要為大家詳細介紹了RecyclerView使用payload實現(xiàn)局部刷新,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10
Android EditTextView 實現(xiàn)帶空格分隔的輸入(電話號碼,銀行卡)
這篇文章主要介紹了Android EditTextView 實現(xiàn)帶空格分隔的輸入(電話號碼,銀行卡)的相關(guān)資料,需要的朋友可以參考下2018-02-02
JetPack Compose底部導航欄的實現(xiàn)方法詳解
開發(fā)一個新項目,底部導航欄一般是首頁的標配,在以前的xml布局中,我們可以很輕松的是用谷歌提供的BottomNavigationView或者自定義來實現(xiàn)底部導航的功能,在Compose中也有也提供了一個類似的控件androidx.compose.material.BottomNavigation2022-09-09
Android編程之截屏實現(xiàn)方法(包括scrollview與listview)
這篇文章主要介紹了Android編程之截屏實現(xiàn)方法,包括截取scrollview與listview屏幕的相關(guān)技巧,以及截屏圖片的生成與保存技巧,需要的朋友可以參考下2015-11-11
android TextView中識別多個url并分別點擊跳轉(zhuǎn)方法詳解
在本篇文章里小編給大家整理的是關(guān)于android TextView中識別多個url并分別點擊跳轉(zhuǎn)方法詳解,需要的朋友們可以學習參考下。2019-08-08

