
這個效果在前幾年一直沒有思路實作,網上的資料也很少,甚至沒有,實作程序中最多想到的就是在滾動的時候去setNativeProps,但是在弄的程序中總會出現布局抖動,而且抖動特別明顯,幾乎不可用,隨著rn的更新迭代,也隨之出現了很多性能較好的影片庫,這個效果今天在閑魚時間拿出來再做一次,它變得如此容易了,
必備第三方庫:react-native-reanimated
效果簡述:
布局下方是滾動區,上方看做一個headerBar,滾動的程序中 headerBar是固定的且隨滾動距離變化高度,且搜索欄會伸縮向上,
我試過這樣做:
<View>
<View>
{/*headerBar*/}
</View>
{/*scroll*/}
<ScrollView>
</ScrollView>
</View>
我的一次次嘗試告訴我這樣是不可以的,我通過ScrollView onScroll回呼 其中配合使用了影片庫reanimated的強大hook useAnimatedScrollHandler,依然做出來效果不堪入目,抖動劇烈,
那怎么辦? 換思路? 固定區域不放外面,放哪? 放scrollView? 回想,放進去也不是固定不了,想想上一篇仿飛豬效果不也是放滾動區內部了?擼起袖子干!!!
我的實作與嘗試:

首先把這個view在滾動的時候固定住,我這里添加了zIndex , 因為我在除錯程序中,發現后渲染的layout層級高于前置渲染layout,會覆寫,做成了飛豬布局,這里很簡單 我們調整下層級就ok了,
然后就是處理我們的headerBar,先看下圖

我圈住的部分就是headerBar,這里我們把搜索欄 放置在跟headerBar同一級下,接下來,在滾動的時候,需要做3件事
- 調整searchBar的寬度與高度,并且加阻尼
- 調整headerBar的高度,加阻尼
- 超值判斷,headerBar最小高度應該等值與一個searchbar的高度,searchbar的最小寬度應該等于 螢屏寬度減去右邊layout的寬度且減去其自身的邊距值,
注意??:這里我們需要設定父級alignItems:
“flex-start”,這樣你在變化寬度的時候,searchbar就是按照父級的約束去改變,android中是通過約束布局去對左右相對約束去做的,我們rn目前只能這樣子做,相對來說,android更加規范!!!
貼代碼:
const JdScrollPage = props => {
const { width } = useWindowDimensions();
const translationY = useSharedValue(0);
const maxWid = width - 100 - 20;
const scrollHandler = useAnimatedScrollHandler((event) => {
translationY.value = event.contentOffset.y;
}, []);
const headerViewAni = useAnimatedStyle(() => {
const val = width - 20 - translationY.value;
return {
width: (val <= maxWid) ? maxWid : val,
};
}, []);
const fixedView = useAnimatedStyle(() => {
return {
transform: [
{
translateY: translationY.value,
},
],
};
});
const parentBlackView = useAnimatedStyle(() => {
const val = 100 - translationY.value / 8;
return {
height: val <= 50 ? 50 : val,
};
});
return (
<View style={{ flex: 1 }}>
<Animated.ScrollView onScroll={scrollHandler}>
<Animated.View style={[{ alignItems: "flex-start",zIndex:10 }, fixedView]}>
<Animated.View style={[styles.headerLayout, parentBlackView]}>
<View style={styles.logoLayout}>
<Image source={require('./logo.jpg')} style={styles.logoPic} resizeMode={"contain"}/>
</View>
<View style={styles.rightLayout}>
<Text>this is layout</Text>
</View>
</Animated.View>
{/*search bar*/}
<Animated.View style={[styles.search,{width:width-20}, headerViewAni]}>
<Text>請輸入搜索內容</Text>
</Animated.View>
</Animated.View>
{/*scroll content*/}
<View style={{ backgroundColor: "#ccc", height: 80 }}>
<Text>hello1</Text>
</View>
<View style={{ backgroundColor: "#ccc", height: 80 }}>
<Text>hello</Text>
</View>
<View style={{ backgroundColor: "#ccc", height: 80 }}>
<Text>hello</Text>
</View>
</Animated.ScrollView>
</View>
);
};
如果想改成,美團,拼多多的那種搜索欄效果,我們只需要把

alignItem:“flex-start” 改成“center”,就可以實作基本一致的效果,你可以根據實際需求稍加調整,就可以完美實作這個互動效果了
最后在貼上github地址:點擊這里查看demo 分支切換到:jdExample
怎么樣,rn現在去做這些東西還是比較簡單的吧,歡迎小伙伴們給我留言評論,互相學習!
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/402770.html
標籤:其他
上一篇:Android事件分發機制
下一篇:同一局域網下安卓真機無線除錯
