【问题标题】:Base Activity extending Activity ViewBinding CrashBase Activity 扩展 Activity ViewBinding 崩溃
【发布时间】:2020-11-28 18:30:03
【问题描述】:

我的基本活动扩展了我的所有其他活动。 Base Activity 具有工具栏、进度条和其他在整个 Activity 中相似的逻辑方法等功能

从 ButterKnife 迁移到 ViewBinding 后,从父基扩展的子 Activity 无法访问其中的方法,应用程序崩溃。

以下是基本活动代码

pubic class BaseActivity extends AppCompatActivity {


    private ActivityBaseBinding activityBaseBinding;

 

    @Override
    public void setContentView(int layoutResID) {
        activityBaseBinding = ActivityBaseBinding.inflate(getLayoutInflater());

        View  view = getLayoutInflater().inflate(layoutResID, activityBaseBinding.container, false);

        if (layoutResID == R.layout.activity_home) {
            activityBaseBinding.toolbarTitle.setVisibility(View.GONE);
        } else if (layoutResID == R.layout.activity_my_account) {
            activityBaseBinding.toolbarTitle.setVisibility(View.VISIBLE);
        } else {
            activityBaseBinding.toolbarTitle.setVisibility(View.GONE);
        }

        activityBaseBinding.container.addView(view);
        setContentView(activityBaseBinding.getRoot());
        activityBaseBinding.imgBackArrow.setOnClickListener(v -> onBackPressed());

    }

如果我尝试从子活动访问基础中的工具栏,这是我得到的错误

java.lang.RuntimeException:无法启动活动 组件信息{com.iowave.scheduler/com.example.myaccount.views.MyAccount}: java.lang.NullPointerException:尝试从字段中读取 'com.google.android.material.appbar.MaterialToolbar com.example.databinding.ActivityBaseBinding.toolbarTitle' 上 空对象引用

这是我的孩子活动的代码

public class MyAccount extends BaseActivity implements MyAccountImpl {

    private NavController navController;


    private ActivityMyAccountBinding activityMyAccountBinding;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityMyAccountBinding = ActivityMyAccountBinding.inflate(getLayoutInflater());
        View view = activityMyAccountBinding.getRoot();
        setContentView(view);
             }
}

据我了解,视图绑定只是绑定子视图并从后台删除所有其他绑定。

【问题讨论】:

  • 您是否意识到您覆盖了setContentView(int) 但使用了setContentView(view)?更不用说这种设计充其量是有问题的。我认为每个xml 文件都有自己的绑定类,您不能将一个活动用于另一个活动。绑定类不关心您的活动是否继承另一个活动,它们是为每个xml 文件从头开始制作的。
  • 是的,确实如此,但这会减少代码,从而使应用程序对内存更加友好。这种架构为我提供了多个活动中的可重用代码。@Ace 如果你能建议我一个更好的方法,请分享我想检查一下。谢谢
  • 扩展基本活动不是问题,读取基本活动的 xml 绑定是问题。您可以保留基本活动及其子类,但不要为其创建 xml 文件。在您的 xml 文件中使用 <include>s 以实现布局的可重用性。
  • 我不确定我是否理解您的第一句话。我之前说过,您可以为共享逻辑扩展一个基本活动,只是不要期望它的xml 布局也会被神奇地共享。此外,是的,单活动应用程序(带有新导航、viewModel 等)也很好。但不要强制“每一个片段”如果它们不应该是。
  • 解决上述具体问题的方法是修复未使用的覆盖 + 不要将 xml 文件提供给 BaseActivity,尤其是“不要指望它会被继承”。

标签: java android android-viewbinding


【解决方案1】:

将此方法用于基本活动模式。

    abstract class  BaseActivity1<Binding extends ViewBinding> extends AppCompatActivity {

    Binding binding;

    abstract  Binding getBinding();

    void  initBinding(){
        binding=getBinding();
    }
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.initBinding();
        setContentView(binding.getRoot());
    }  
}

然后

class MainActivity extends BaseActivity1<ActivityMainBinding>{
    @Override
    ActivityMainBinding getBinding(){
        return ActivityMainBinding.inflate(getLayoutInflater());
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多