数据绑定不适用于覆盖 BottomNavActivity 的 BaseActivity。 setContentView 调用了两次

Databinding not working with BaseActivity that overrides BottomNavActivity . setContentView called twice

Activity 不工作,因为 setContentView 被调用了两次。

这是我的activity_main布局:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <import type="android.view.View"/>
       <variable
           name="viewmodel"
           type="com.project.viewmodel.MainViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
            android:id="@+id/pullToRefresh"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_marginTop="?attr/actionBarSize"
            android:background="@color/transparent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toTopOf="@id/bottom_nav">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/content_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
                  <androidx.viewpager.widget.ViewPager
                    android:id="@+id/view_pager"
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:clipToPadding="false"
                    android:foregroundGravity="center"
                    android:overScrollMode="never"
                    app:layout_constraintBottom_toTopOf="@+id/tabLayout"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@+id/search_image_view"
                    android:visibility="@{safeUnbox(viewmodel.dataLoading) ? View.VISIBLE : View.VISIBLE}"/>
         
            </androidx.constraintlayout.widget.ConstraintLayout>

        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottom_nav"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_marginTop="@dimen/_5sdp"
            android:background="@drawable/bottom_nav_background"
            android:clipChildren="false"
            android:visibility="visible"
            app:elevation="8dp"
            app:labelVisibilityMode="labeled"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintVertical_bias="1"
            app:menu="@menu/bottom_nav" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

MainActivity.kt

class MainActivity : BottomNavActivity() {
    private lateinit var binding: ActivityWeatherNewBinding

    override fun getContentViewId(): Int {
        return R.layout.activity_main
    }

    override fun getNavigationMenuItemId(): Int {
        return R.id.nav_main
    }

    override fun onCreate(savedInstanceState: Bundle?) {

        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        super.onCreate(savedInstanceState)
}
}

BottomNavigationActivity.java 用于设置再次调用 setContentView 的 BottomNavigation。

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getContentViewId());
        bottomNavigationView = findViewById(R.id.bottom_nav);
        bottomNavigationView.setOnNavigationItemSelectedListener(this);
    }
 @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        int itemId = item.getItemId();
        int currentItemId = getNavigationMenuItemId();
        if (itemId == currentItemId) {
            if (itemId == R.id.one) {
                
            }
            return false;
        }
        if (itemId == R.id.two) {
            startActivity(new Intent(this, TwoActivity.class));
        } 
        return true;
    }

    private void updateNavigationBarState() {
        int actionId = getNavigationMenuItemId();
        selectBottomNavigationBarItem(actionId);
    }

    void selectBottomNavigationBarItem(int itemId) {
        Menu menu = bottomNavigationView.getMenu();
        for (int i = 0, size = menu.size(); i < size; i++) {
            MenuItem item = menu.getItem(i);
            boolean shouldBeChecked = item.getItemId() == itemId;
            if (shouldBeChecked) {
                item.setChecked(true);
                break;
            }
        }
    }

    protected abstract int getContentViewId();

    protected abstract int getNavigationMenuItemId();

问题 是我无法修改 BottomNavActivity,我正在处理这个新的 MainActivity,我必须在其中扩展 BottomNavActivity 用于底部导航。

当我在设置 DataBinding 后在 MainActivity 中调用 super.onCreate() 时,底部导航工作正常但 Viewpager 不显示。当我在绑定之前设置 onCreate 时,viewpager 显示但底部导航不起作用。 我试图在互联网上寻找替代解决方案,但我找不到任何东西,问题仍然存在。 我知道我正面临这个问题,因为 setContentView 被调用了两次。但我找不到解决方法。

两种可能的解决方案:

  1. 我可以在 MainActivity 上再次设置底部导航侦听器,但 BottomNavActivity 将没有意义。
  2. 或者我可以只使用旧的 findViewById 并完全删除数据绑定。

我的问题是,有没有什么方法可以解决这个问题,同时仍然使用数据绑定并利用 BottomNavActivity? 任何建议或想法都会有很大帮助,我们将不胜感激。

找到解决方案

在MainActivity中我先设置了绑定变量,然后我将变量发送给BottomNavactivity

binding = DataBindingUtil.setContentView(this, R.layout.activity_weather_new)
setDataBinding(binding)
super.onCreate(savedInstanceState)

BottomNavActivity

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(binding == null){
            setContentView(getContentViewId());
            bottomNavigationView = findViewById(R.id.bottom_nav);
        }else {
            bottomNavigationView = binding.bottomNav;

        }
        bottomNavigationView.setOnNavigationItemSelectedListener(this);
    }
public void setDataBinding(ActivityWeatherNewBinding activityWeatherNewBinding){
        binding = activityWeatherNewBinding;
    }

使用绑定变量获取 bottomNav 视图,从而防止第二次调用 setContentView