Android:Use ButterKnife in Activity extending from another activity
Asked Answered
L

3

3

I wanted navigation drawer in all my activities.So i used a BaseActivity for Navigation drawer and extended other activities from base activity.Base activity has Navigation drawers. Dashboard activity is extending base activity but it raises exception when i try to use butterknife to bind views saying

java.lang.IllegalStateException: Required view 'dashboard_frameLayout' with ID 2131558517 for field 'frameLayout' was not found.  

here are the relevant files
BaseActivity.java

public class BaseActivity extends AppCompatActivity {

@BindView(R.id.toolbar) Toolbar toolbar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_base);
    ButterKnife.bind(this);

    //set toolbar and both Navigation Drawer

}

DashboardActivity.java

public class DashBoardActivity extends BaseActivity {

@BindView(R.id.dashboard_frameLayout)
FrameLayout frameLayout;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    View view = getLayoutInflater().inflate(R.layout.activity_dashboard,frameLayout);
    ButterKnife.bind(this,view);

    init();
}

private void init() {

    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dashboard_frameLayout);
    if(fragment != null){
        Utils.getInstance().addFragment(this,new Fragment_Dashboard(),R.id.dashboard_frameLayout);
    }
}
}

activity_dashboard.xml

<FrameLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dashboard_frameLayout"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

why the framelayout was not found in dashboard activity?

Latinist answered 14/11, 2016 at 6:46 Comment(0)
P
1

I did something similar in my code.

My goal is to have a base drawer activity with one drawer that i reuse in different activities, so i want to be able to use activity_base_drawer layout in all activities, but change the content by inflating new views into it.

in my base activity (which is a nav drawer activity) i have this protected method

protected void inflateContent(@LayoutRes int inflatedResID){
    setContentView(R.layout.activity_base_drawer);

    LinearLayout contentContainer = ButterKnife.findById(this, R.id.content_container);

    getLayoutInflater().inflate(inflatedResID, contentContainer);
    ButterKnife.bind(this);

    setSupportActionBar(toolbar);

    setupNavDrawer();
}

I send the base nav drawer layout to setContentView() which has a linear layout that is the container that i want to inflate new layouts into it for each activity that extends my base activtiy

As you can see, LinearLayout contentContainer is using findById not @BindView. I have to do it this way because I need to inflate a view into the content container before i call ButterKnife.bind(this);

After finding the content container layout I inflate a view into it using getLayoutInflater().inflate(inflatedResID, contentContainer);

Then I call ButterKnife.bind(this);

Finally, I do some setup methods that depend on layouts that are being bound using @BindView in the base activity class.

and in any extending activity the onCreate() looks like this, where i send the ID of the layout I want to inflate to inflateContent()

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    inflateContent(R.layout.content_main);
}
Polythene answered 22/5, 2017 at 9:34 Comment(0)
S
0

My wrong I didn't check the question carefully.

Edited:

In your example you have bound the views twice. One in BaseActivity and the other in DashBoardActivity.

  • No need to do that in BaseActivity. But make sure you have a toolbar with id R.id.toolbar in sub-class activities.
  • No need to inflate layout R.layout.activity_dashboard, you've done that in setContentView. It should be like this:

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dashboard);
        ButterKnife.bind(this);
    
        init();
    }
    

After you trigger ButterKnife.bind(this), the frameLayout is ready for use. Make sure framelayout id dashboard_frameLayout exists in your activity layout file.

Staple answered 14/11, 2016 at 7:39 Comment(8)
read the question properly . Its not about fragments.Its about framelayout which is present in activity_dashboard.xml .It is null even after binding views.Latinist
And your activity layout should have a toolbar and framelayout defined inside a container. I don't see the toolbar in it.Staple
if i use setContentView(R.layout.activity_dashboard) in the subclass.It will override the layout.I wont get navigation drawer inside this activit.yLatinist
It is inheriting the toolbar and navigation drawer from base activity.Latinist
@Androidjack No you can't setContentView twice. This is not an incremental process. To reuse navigation drawer, you can defined an XML file, e.g. navigation_drawer.xml and defined your navigation drawer in it. Then in each sub-class activity use:Staple
<include layout="@layout/navigation_drawer" />Staple
i forgot to remove setContentView while posting. I am not using contentView twice.I have already defined navigation drawer and toolbar in my base activityLatinist
Now i am extending it in other activities.Latinist
L
0

In your case "ButterKnife.bind(this)" (from onCreate() of BaseActivity) is being called before OnCreate() of DashBoardActivity. So when ButterKnife try's to bind the views of activity_base, it is not able to find the view id R.id.dashboard_frameLayout in activity_base layout, that throws the exception.

To bind the view one should add a container like view group such as RelativeLayout to activity_base. Create a addViews() method in BaseActivity. Then add the view activity_dashboard layout to that container from onCreate() of DashBoardActivity by calling addViews() of Baseactivity. Now you can add "ButterKnife.bind(this)" to addViews() method (and you should not call ButterKnife.bind anywhere else in both activity). One thing to note here you have to get the view id reference of container in BaseActivity simply by using findViewById, remaining views will get bind by ButterKnife.

Lora answered 16/4, 2017 at 16:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.