- 實(shí)現(xiàn)的效果:
- 頁面向上滑動(dòng)有吸頂?shù)男Ч?/li>
-
便民服務(wù)芹枷,查詢服務(wù) ...
所在的tabBar
與頁面下方對(duì)應(yīng)的模塊內(nèi)容一一對(duì)應(yīng)斤富。 - 頁面滑動(dòng)對(duì)應(yīng)的
tabBar
的title
居中偏移。 - 編輯模式下:數(shù)據(jù)的
新增
與刪除
份帐。
- 效果展示:
-
實(shí)現(xiàn)吸頂?shù)拇a(噗~感覺這個(gè)沒啥好寫 ...... 很尷尬):
—— 段子手是運(yùn)用ScrollView
==>onScroll
==>e.nativeEvent.contentOffset.y
獲取頁面滑動(dòng)的當(dāng)前坐標(biāo)膏萧;
然后和頁面初次加載時(shí)tabBar
==>onLayout
==>e.nativeEvent.layout.y
的值做比較獲取狀態(tài)。this.moveHeight = e.nativeEvent.contentOffset.y; if (this.moveHeight >= typeY) { this.setState({ positionType: true, }) } else { this.setState({ positionType: false }) }
-
實(shí)現(xiàn)滑動(dòng)模塊和標(biāo)題一一對(duì)應(yīng)代碼(這個(gè)有點(diǎn)篇幅):
-
先說:點(diǎn)擊標(biāo)題饮怯,對(duì)應(yīng)的模塊自動(dòng)置頂
- 首先初次加載時(shí)闰歪,我把
tabBar
下的各個(gè)模塊的y
坐標(biāo)都存下來,push
到數(shù)組中蓖墅,并且對(duì)應(yīng)的模塊下標(biāo)i
也存起來库倘。
//保存 模塊的下標(biāo)和 y 軸 let params = { key: i, tmpY: e.nativeEvent.layout.y }; //數(shù)組去重(判斷命名的變量不建議用 type) let typePis = tmpArr.some(v => v.key == params.key); if (typePis) { tmpArr.filter((v) => { return v.key != params.key }) } else { tmpArr.push(params); } break;
- 去重是因?yàn)槲數(shù)脑颍瑫?huì)導(dǎo)致頁面的
onLayout
重新加載论矾。 - 這里還有一個(gè)小坑:模塊返回的坐標(biāo)順序并不是按頁面展示順序來的教翩。
- 拿到模塊的坐標(biāo)數(shù)組
tmpArr
后,根據(jù)點(diǎn)擊tabBar
的下標(biāo)index
和tmpArr
的key
去匹配贪壳,一致時(shí)取出tmpArr
對(duì)應(yīng)的tmpY
值饱亿,根據(jù)該值去計(jì)算頁面的偏移量。
let y; tmpArr.map((v, i) => { if (v.key == index) { y = v.tmpY; } }); // 頁面中模塊的 y 軸移動(dòng) (typeY: tabBar 的坐標(biāo), // y:模塊的坐標(biāo)彪笼,頭部 固定位置的搜索: autoHeight(45)) this.refs.refMoveHeight.scrollTo({y: typeY + y - autoHeight(45)});
- 在點(diǎn)擊
tabBar
最后的標(biāo)題钻注,模塊的內(nèi)容的高度不夠去偏移到置頂?shù)奈恢玫奶幚恚ǜ鶕?jù)已有的內(nèi)容高度,去自適應(yīng)填充空白區(qū)域)配猫。- 保存最后一個(gè)模塊的
y
軸
// i:就是點(diǎn)擊標(biāo)題的下標(biāo)幅恋;typeList:是標(biāo)題數(shù)組。 if (i == typeList.length - 1) { this.setState({ listCellHeight: e.nativeEvent.layout.y }) }
- 在最后的一個(gè)模塊后面添加一個(gè)高度為
1
的View
泵肄,然后保存它的坐標(biāo)footHeight = e.nativeEvent.layout.y
捆交,接著再設(shè)置一個(gè)填充空白頁面View
,高度為屏幕全高 - (footHeight - listCellHeight - typeY + autoHeight(45))
凡伊。
- 保存最后一個(gè)模塊的
- 首先初次加載時(shí)闰歪,我把
-
再說下滑動(dòng)模塊和
tabBar
的標(biāo)題對(duì)應(yīng)- 獲取手勢(shì)在屏幕上的滑動(dòng)方向零渐,把
<=
當(dāng)前頁面滑動(dòng)高度的模塊都塞選出來,然后取出最大的下標(biāo)系忙,然后和tabBar
中的標(biāo)題下標(biāo)去匹配诵盼,一致則標(biāo)題顯示高亮。let maxValue = 0; if (this.moveHeight > e.nativeEvent.contentOffset.y) { tmpArr.map((v, i) => { if (e.nativeEvent.contentOffset.y >= (typeY + v.tmpY - autoHeight(45))) { // console.log(i + '下下下'); //因?yàn)槟K高度的下標(biāo)不是按在頁面中的位置返回的银还,所以和 tabBar 的下標(biāo)并不能一一對(duì)應(yīng)风宁,所以要塞選出下標(biāo)的最大值 if (tmpArr[i].key >= maxValue) { maxValue = tmpArr[i].key } // console.log(maxValue + 'maxValue下========='); } } ) } else { tmpArr.map((v, i) => { if (e.nativeEvent.contentOffset.y >= (typeY + v.tmpY - autoHeight(45))) { // console.log(i + '下下下'); //因?yàn)槟K高度的下標(biāo)不是按在頁面中的位置返回的,所以和 tabBar 的下標(biāo)并不能一一對(duì)應(yīng)蛹疯,所以要塞選出下標(biāo)的最大值 if (tmpArr[i].key >= maxValue) { maxValue = tmpArr[i].key } // console.log(maxValue + 'maxValue上======'); } } ) } this.state.currentIndex = maxValue;
- 獲取手勢(shì)在屏幕上的滑動(dòng)方向零渐,把
-
-
實(shí)現(xiàn)頁面滑動(dòng)對(duì)應(yīng)的
tabBar
的title
居中偏移代碼-
獲取屏幕
width
的寬度的一半戒财。let widthHalf = 屏幕寬度 / 2;
-
獲取到
tabBar
中各個(gè)標(biāo)題位置的width
,同時(shí)保存對(duì)應(yīng)的挑剔位置的下標(biāo)捺弦,數(shù)組為tmpArrX
饮寞。//保存 tabBar 的下標(biāo)和 width let param = { index: i, tmpX: e.nativeEvent.layout.width }; //數(shù)組去重 let tmpType = tmpArrX.some(v => v.index == param.index); if (tmpType) { tmpArrX.filter((v) => { return v.index != param.index }) } else { tmpArrX.push(param); }
-
拿到點(diǎn)擊
tabBar
的下標(biāo),獲取到這個(gè)下標(biāo)之前的模塊width
列吼。//獲取 index 之前模塊 width let widthX = 0; //獲取選中的 width let indexWidth; for (let i = 0; i <= index; i++) { // console.log('i===' + i); tmpArrX.map((item, key) => { if (item.index == i) { widthX += item.tmpX } if (index == item.index) { indexWidth = item.tmpX } }) }
-
根據(jù)判斷出來是不是
tabBar
中最后一個(gè)標(biāo)題幽崩,然后拿widthX
和indexWidth
然后去判斷編寫邏輯。let moveX; // index*20 是每個(gè)模塊的空隙 20 if (widthX + index * 20 > widthHalf && index != tmpArrX.length - 1) { moveX = (widthX - widthHalf + indexWidth) / 2 } else if (index == tmpArrX.length - 1) { //index + 1 :間距比個(gè)數(shù)多一個(gè); 10 :marGinLeft = 10 moveX = (index + 1) * 20 + widthX - SCREEN_WIDTH + 10 } // 頁面中 tabBar 的 x 軸移動(dòng) this.refs.moveX.scrollTo({x: autoWidth(moveX)})
-
-
實(shí)現(xiàn)編輯模式下:數(shù)據(jù)的
新增
與刪除
的代碼(段子手快餓死了寞钥,寫不動(dòng)注釋了 ......)//數(shù)組的加減 _addOrDelete(keyType, data, i) { console.log('data===' + JSON.stringify(data) + '===' + i); //更改 severListType 的數(shù)據(jù) const {severListType, headList}=this.state; let tmpType = severListType.some(item => item.id === data.id); switch (keyType) { case 1: // severListType.splice(i, 1); if (tmpType) { // tmpSeverId :用來存儲(chǔ)選中的截取的 id this.state.severListType = severListType.filter((item) => { return item.id != data.id }); //編輯模式下慌申,是否為已有模塊, true:加號(hào),false:減號(hào) data.select = !tmpType; } break; case 2: case 3: if (!tmpType) { if (severListType.length > 10) { RootToast.show('首頁最多添加 11 個(gè)應(yīng)用') } else { severListType.push(data) } } else { //獲取輸入的值和在另一個(gè)模塊數(shù)組中的下標(biāo)理郑,然后刪除 console.log('data1===' + JSON.stringify(data) + '===ss' + i); console.log('severListType===' + JSON.stringify(severListType)); this.state.severListType = severListType.filter((item) => { return item.id != data.id }); data.select = !tmpType; } break; } //刷新數(shù)據(jù) this.setState({ severListType: this.state.severListType }, () => { // console.log('severListType===' + JSON.stringify(this.state.severListType)); }); }
TIP:
- 吸頂效果在
android
低配中會(huì)出現(xiàn)卡頓現(xiàn)象蹄溉。 - 頁面滑動(dòng)對(duì)應(yīng)的
tabBar
的title
居中偏移(我的寫法還是有問題的,還有就是模塊滑動(dòng)時(shí)tabBar
對(duì)應(yīng)居中也會(huì)有卡頓)您炉。
新增手勢(shì)
-
TouchableHighlight
屬性
名稱 | 屬性 | 注釋 |
---|---|---|
accessibilityComponentType | View.AccessibilityComponentType | 設(shè)置可訪問的組件類型 |
accessibilityTraits | View.AccessibilityTraits | 設(shè)置訪問特征 |
accessible | bool | 設(shè)置當(dāng)前組件是否可以訪問 |
delayLongPress | View.AccessibilityTraits | 設(shè)置當(dāng)前組件是否可以訪問 |
accessibilityTraits | number | 設(shè)置延遲的時(shí)間柒爵,單位為毫秒。從 onPressIn 方法開始赚爵,到 onLongPress 被調(diào)用這一段時(shí)間 |
delayPressIn | number | 設(shè)置延遲的時(shí)間餐弱,單位為毫秒宴霸,從用戶觸摸控件開始到 onPressIn 被調(diào)用這一段時(shí)間 |
delayPressOut | number | 設(shè)置延遲的時(shí)間,單位為毫秒膏蚓,從用戶觸摸事件釋放開始到 onPressOut 被調(diào)用這一段時(shí)間 |
onLayout | function | 當(dāng)組件加載或者改組件的布局發(fā)生變化的時(shí)候調(diào)用瓢谢。調(diào)用傳入的參數(shù)為 {nativeEvent:{layout:{x,y,width,height}}} |
onLongPress | function | 當(dāng)用戶長時(shí)間按壓組件(長按效果)的時(shí)候調(diào)用該方法 |
onPress | function | 當(dāng)用戶點(diǎn)擊的時(shí)候調(diào)用(觸摸結(jié)束)。 但是如果事件被取消了就不會(huì)調(diào)用驮瞧。(例如:當(dāng)前被滑動(dòng)事件所替代) |
onPressIn | function | 用戶開始觸摸組件回調(diào)方法 |
onPressOut | function | 用戶完成觸摸組件之后回調(diào)方法 |
pressRetentionOffset | {top: ,left: ,bottom: ,right: } | 該設(shè)置當(dāng)視圖滾動(dòng)禁用的情況下氓扛,可以定義當(dāng)手指距離組件的距離。當(dāng)大于該距離該組件會(huì)失去響應(yīng)论笔。當(dāng)少于該距離的時(shí)候采郎,該組件會(huì)重新進(jìn)行響應(yīng)。確保你傳入一個(gè)常量來減少內(nèi)存分配狂魔。 |
段子手不才蒜埋,歡迎來補(bǔ)充
- 由于篇幅原因,具體想要知道整個(gè)效果圖的代碼或者有補(bǔ)充地方的可以加技術(shù)群:631730313