-1

I have a BaseActivity class that extends AppCompatActivity to display a common navigator toolbar, and also implements some other custom listener interfaces for a drawer layout as well. This BaseActivity class is being utilized by many other activity classes in the same project as well, and it will not be practical to refactor it.

I have now created a new activity class, but this one implements view binding. Everything works well, except that it does not seem to display the BaseActivity layout, that is, the common navigator toolbar and the drawer.

Is there a way to implement the layouts of this base activity into this new view-binding class? Through some interface class, perhaps?


Clarification

When the class that is using the BaseActivity class is using conventional layout inflaters (eg: setContentView(R.layout.main)), the common navigator and drawer layouts from the BaseActivity are displayed correctly.

But when the class that is using the BaseActivity class is using view binding layout inflaters (eg: setContentView(binding.root)), the common navigator and drawer layouts from the BaseActivity are not displayed at all.


Code Extracts

public class BaseActivity extends BaseActivityGroup implements DrawerLayout.DrawerListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityManager.getInstance().addActivity(this);
        super.setContentView(R.layout.base_activity);
    }
}

This activity displays the BaseActivity common navigator and drawer layouts, as well as its own layout (R.layout.old_style_activity):

public class OldStyleActivity extends BaseActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.old_style_activity);
    }
}

This activity only displays its own layout (binding.getRoot()), but not the BaseActivity's layout:

import com.myapp.new.databinding.ActivityNewStyleBinding;

public class NewStyleActivity extends BaseActivity {
    private ActivityNewStyleBinding binding;    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityNewStyleBinding.inflate(getLayoutInflater());
        View viewBinding = binding.getRoot();
        setContentView(viewBinding);
    }
}
iSofia
  • 1,412
  • 2
  • 19
  • 36
  • Sounds like your `BaseActivity` has overridden the `setContentView(int)` method to add the drawer and navigation, but has neglected to consider the `setContentView(View)` overload. – Mike M. May 02 '22 at 15:48
  • That sounds very likely, @MikeM. Would you have any idea how I could avoid this override? – iSofia May 02 '22 at 15:50
  • If you need specific suggestions, you'll have to show us your code. – Mike M. May 02 '22 at 15:52
  • @MikeM. I've added some code extracts to provide a better idea. – iSofia May 02 '22 at 17:04
  • Somewhere in your code, likely in `BaseActivity` or `BaseActivityGroup`, you have something like `@Override public void setContentView(int layoutResID) { … }`. That is presumably where the subclasses' layouts are inflated into the drawer and navigation setup from the `base_activity` layout that was set with the `super.setContentView()` call. You need to move or copy that functionality to `@Override public void setContentView(View view) { … }`, because that's the `setContentView()` overload that you're now using with the binding object. Follow me? – Mike M. May 02 '22 at 17:12
  • @MikeM. Sorry Mike, but not really. I'm quite lost. – iSofia May 02 '22 at 17:28
  • Did you find the `public void setContentView(int layoutResID)` override in your code? If so, post that. – Mike M. May 02 '22 at 17:29

2 Answers2

0

ViewBinding generate the class from activity_new_style.xml and because of that it do not know about any OOP prinicples... and sory this is in Kotlin but your IDE can change it to Java... the logic is the same

abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
    
        private var _binding: VB? = null
        
        val childActivityBinding: VB
                get() = _binding as VB
    
        abstract fun inflateLayout(
            parent: FrameLayout,
            inflater: LayoutInflater
        ): VB
    
        lateinit var baseActivityBinding: ActivityBaseBinding
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            baseActivityBinding = ActivityBaseBinding.inflate(layoutInflater)
            _binding = inflateLayout(baseActivityBinding.root.layout_container, layoutInflater)
    
            val coordinatorLayout = baseActivityBinding.root
            .
            .// some base activity processes like setting Snackbar etc.
            val snack = coordinatorLayout.snack
            .
    
            super.setContentView(coordinatorLayout)
        }
    }

public class MainActivity extends BaseActivity<ActivityMainBinding> {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    @NonNull
    @Override
    public ActivityMainBinding inflateLayout(@NonNull FrameLayout parent, @NonNull LayoutInflater inflater) {
        return ActivityMainBinding.inflate(inflater, parent, true);
    }
}

I recoment that you use fragemnt instead of NewStyleActivity and your will have refernce on you parent activity which is composition not inheritance

-1

You can't show two activities on screen, activity should host fragments

  • It works with other standard non-view-binding activities. – iSofia May 02 '22 at 11:32
  • Do you maybe do not load base acitivity layout in onCreate method of your new activity class – EffectiveIvana May 02 '22 at 11:35
  • There's no way to load the BaseActivity separately. It should be automatically loaded when super.onCreate(savedInstanceState) is called. – iSofia May 02 '22 at 13:01
  • If you have viewBinfing, this method setContentView(R.layout.new_layout); shoud be setContentView(binding.root); binding needs to be initialized befire that method – EffectiveIvana May 02 '22 at 13:04
  • I hope i helped – EffectiveIvana May 02 '22 at 13:04
  • binding = ActivityYourBinding.inflate(layoutInflater) – EffectiveIvana May 02 '22 at 13:06
  • All the binding elements are correctly implemented, and all the layouts of the activity are displayed properly and completely. But the common layouts from the BaseActivity are not displayed. – iSofia May 02 '22 at 15:36
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 03 '22 at 05:24