【发布时间】:2021-08-27 18:02:15
【问题描述】:
如何创建一个底部导航栏,其底部导航栏始终位于所选选项的中心?
我尝试过使用 TabLayout,已经实现了居中功能,但无法实现对齐功能。
设计部分:
<xxx.xxx.xxx.CenteringTabLayout
android:id="@+id/modes"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_alignParentBottom="true"
app:tabRippleColor="@android:color/transparent"
app:tabIndicatorFullWidth="false"
app:tabMode="scrolling"
app:tabIndicator="@drawable/mode_indicator"
app:tabGravity="center"
app:tabIndicatorHeight="30dp"
android:background="@android:color/transparent"
android:layout_marginVertical="12dp"
android:layout_marginHorizontal="8dp"/>
CenteringTabLayout.java
package xxx.xxx.xxx;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import androidx.camera.extensions.ExtensionMode;
import androidx.core.view.ViewCompat;
import com.google.android.material.tabs.TabLayout;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;
public class CenteringTabLayout extends TabLayout {
private final ArrayList<Integer> snapPoints = new ArrayList<>();
private int count = 0;
public CenteringTabLayout(Context context) {
super(context);
}
public CenteringTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CenteringTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private int sp = 0;
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
ViewGroup tabParent = (ViewGroup)getChildAt(0);
View firstTab = tabParent.getChildAt(0);
View lastTab = tabParent.getChildAt(tabParent.getChildCount()-1);
sp = (getWidth()/2) - (firstTab.getWidth()/2);
ViewCompat.setPaddingRelative(getChildAt(0), sp,0,(getWidth()/2) - (lastTab.getWidth()/2),0);
View centerTab = tabParent.getChildAt(tabParent.getChildCount()/2);
centerView(centerTab);
count = getTabCount();
snapPoints.clear();
int widthC = 0;
snapPoints.add(0);
for (int i = 0; i < count; ++i) {
View tabView = tabParent.getChildAt(i);
widthC+=tabView.getWidth()/2;
snapPoints.add(widthC + 19);
widthC+=tabView.getWidth()/2;
}
// widthC += tabParent.getChildAt(count-1).getWidth()/2;
snapPoints.add(widthC);
--count;
Log.i("TAG", Arrays.toString(snapPoints.toArray()));
}
private void centerView(View view){
scrollTo(getRelativeLeft(view) - sp - view.getPaddingLeft() , 0);
}
@Override
protected void onScrollChanged(int x, int t, int oldX, int oldT) {
if(Math.abs(oldX-x)<=1) return;
int i = 0;
while(i<count){
final int p = snapPoints.get(i);
final int n = snapPoints.get(++i);
Log.i("i:P,L,N", i+":"+p+","+x+","+n);
if(x>=p && x<=n){
--i;
if(getSelectedTabPosition()==i) return;
View tabView = Objects.requireNonNull(getTabAt(i)).view;
Log.i("Selected", String.valueOf(Objects.requireNonNull(getTabAt(i)).getText()));
tabView.performClick();
centerView(tabView);
return;
}
ExtensionMode;
}
super.onScrollChanged(x, t, oldX, oldT);
}
private int getRelativeLeft(View myView) {
if (myView.getParent() == myView.getRootView())
return myView.getLeft();
else
return myView.getLeft() + getRelativeLeft((View) myView.getParent());
}
}
我已经粗略研究了其他方法(使用 ViewPager + Button/ImageView 和 FrameLayout、底部导航栏等)[虽然不确定它们是否能满足所有要求],但有人知道或能想到吗有更好的实现方式吗?
【问题讨论】:
-
那不是底部导航栏。那是嵌入到水平 ScrollView 中的视图
-
您能否分享任何参考资料或提供一些关于如何实现这一目标的指导?
标签: android