Common Header in different activities using BaseActivity in android
Asked Answered
E

4

18

I want write code once and use in different activities. I have created a Base Activity class for that . Also the header of all the layouts in different activities are same. I have done that with the help of the <include layout > tag.

Now the Problem is my BaseActivity code is not running. I am trying this first time se don't have much idea about that.

1.)The BaseActivity code is below :

package com.waheguru.app;

import android.R.integer;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

import android.view.View;
import android.view.View.OnClickListener;

import android.widget.Button;
import android.widget.Toast;

public abstract class BaseActivityMenu extends Activity {
    //action id
    private static final int ID_UP     = 1;
    private static final int ID_DOWN   = 2;
    private static final int ID_SEARCH = 3;
    private static final int ID_INFO   = 4;
    private static final int ID_ERASE  = 5; 
    private static final int ID_OK     = 6;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.header);

        ActionItem nextItem     = new ActionItem(ID_DOWN, "Book", getResources().getDrawable(R.drawable.menu_down_arrow));
        ActionItem prevItem     = new ActionItem(ID_UP, "Bookmark", getResources().getDrawable(R.drawable.menu_up_arrow));
        ActionItem searchItem   = new ActionItem(ID_SEARCH, "Find", getResources().getDrawable(R.drawable.menu_search));
        ActionItem infoItem     = new ActionItem(ID_INFO, "Info", getResources().getDrawable(R.drawable.menu_info));
        ActionItem eraseItem    = new ActionItem(ID_ERASE, "Clear", getResources().getDrawable(R.drawable.menu_eraser));
        ActionItem okItem       = new ActionItem(ID_OK, "OK", getResources().getDrawable(R.drawable.menu_ok));

        //use setSticky(true) to disable QuickAction dialog being dismissed after an item is clicked
        prevItem.setSticky(true);
        nextItem.setSticky(true);

        //create QuickAction. Use QuickAction.VERTICAL or QuickAction.HORIZONTAL param to define layout 
        //orientation
        final QuickAction quickAction = new QuickAction(this, QuickAction.VERTICAL);

        //add action items into QuickAction
        quickAction.addActionItem(nextItem);
        quickAction.addActionItem(prevItem);
        quickAction.addActionItem(searchItem);
        quickAction.addActionItem(infoItem);
        quickAction.addActionItem(eraseItem);
        quickAction.addActionItem(okItem);

        //Set listener for action item clicked
        quickAction.setOnActionItemClickListener(new QuickAction.OnActionItemClickListener() {          
            public void onItemClick(QuickAction source, int pos, int actionId) {                
                ActionItem actionItem = quickAction.getActionItem(pos);

                //here we can filter which action item was clicked with pos or actionId parameter
                if (actionId == ID_SEARCH) {
                    Toast.makeText(getApplicationContext(), "Let's do some search action", Toast.LENGTH_SHORT).show();
                } else if (actionId == ID_INFO) {
                    Toast.makeText(getApplicationContext(), "I have no info this time", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getApplicationContext(), actionItem.getTitle() + " selected", Toast.LENGTH_SHORT).show();
                }
            }
        });

        //set listnener for on dismiss event, this listener will be called only if QuickAction dialog was dismissed
        //by clicking the area outside the dialog.
        quickAction.setOnDismissListener(new QuickAction.OnDismissListener() {          
            public void onDismiss() {
                Toast.makeText(getApplicationContext(), "Dismissed", Toast.LENGTH_SHORT).show();
            }
        });
        Button books=(Button)findViewById(R.id.book);
        books.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                Intent intent=new Intent(ExampleActivity.this,List_of_books.class);
                startActivityForResult(intent, 0);
            }
        });
        //show on btn1
        Button btn1 = (Button) this.findViewById(R.id.menu);
        btn1.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                quickAction.show(v);
            }
        });
    }
}

2.) The Activity extended the Base Activity

package com.waheguru.app;

import android.app.Activity;
import android.os.Bundle;

public class ABCActivity extends BaseActivityMenu  {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home);
    }
}

So can any one help me where I am doing something wrong.

Eisenstark answered 20/7, 2012 at 12:43 Comment(1)
Your base activity is called ExampleActivity but your activity extends BaseActivityMenu. I think you are confused.Wyon
C
24

For this you have to create one header.xml which will be included in each and every layout for your activities as follows

header.xml

<RelativeLayout>
  <TextView android:id="@+id/txtHeading"
      .... />
</RelativeLayout>

activity_main.xml

<RelativeLayout>
  <!-- include your header here -->
  <include layout="@layout/header"
     ... />

  <!-- Rest of your views -->

</RelativeLayout>

BaseActivity

abstract class BaseActivity extends Activity {
  protected TextView txtHeading;
  public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
  }


  protected void setHeading(int resId) {
     if(txtHeading == null)
     txtHeading = findViewById(R.id.txtHeading);
     if(txtHeading != null)
       txtHeading.setText(resId);
  }
}

MainActivity

class MainActivity extends BaseActivity {
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      setHeading(R.string.heading_main);
   }
}

You can put as many views you want and manage common things in BaseActivity or BaseListActivity.

Chimaera answered 20/7, 2012 at 12:55 Comment(8)
can you plz elaborate the setheading () more also I want to know that I have used the setContentView(R.layout.header); so what should I do for that. Sorry if my question is stupidEisenstark
don't use header.xml as your contentView, just include it in your activity_main.xml layout as part of your screen UI.Chimaera
I've assumed that my heading textview's id would be txtHeading. so I find it in setHeading() and then set text to textview. Due to inheritance it'll find from activity_main.xml as I've included header.xml into activity_main.xmlChimaera
Yes I have include that in my main xml. But then how can I use the buttons and textviews of that header in my BaseActivity. Because I have to set some click events on them as well.Eisenstark
suppose you have home button on top left of your header then you can define android:onClick="homeClick" in your home button and define this method (i.e., homeClick) into your BaseActivity with prototype public void homeClick(View v) { /* code to go home activity */ }Chimaera
@Kevin - Can you help me out too,heres a link to my question. https://mcmap.net/q/740753/-reusing-the-common-layout-in-android-application/1270865Thumbprint
@KevinAdesara I worked on Click events of the header as you said, but I am not able to perform click events from main activity. Can you help me please. my issue is #43847878Postwar
@kumarSudheer, I've answered your question. Please check it.Chimaera
R
2

If you are making inheritance with activities and your base activity calls setContentView and after that the real activity calls setContentView the last call will set the layout for activity. So if you are looking for a solution where all activies have the same header component the are 2 ways.

  1. For each activity layout xml you include that component

  2. -You make function for baseActivity e.g. setContent(int layout_id) -You call that with your activity always. -Baseactivity inflates a root view with header and inflates layout_id view to that layout. -Then calls the actual setContentView with that component.

Raymonderaymonds answered 20/7, 2012 at 12:59 Comment(4)
I am using the setContentView(R.layout.header); Can you please elaborate the 2nd point more. Sorry I am new in android and java. So need some supportEisenstark
Your base needs to override setContentView, so when you call it in your activity, it gets forwarded to base which will call the Activity.setContentView. Without this you are calling it twice.Raymonderaymonds
So what should I do in that case ?Eisenstark
First you inflate the base layout where you have the header, then you inflate the content layout and add that layout to the baselayout which can for example be vertical LinearLayout, when you have combined these two layout you call Activity.setContentView and pass combined layout to it.Raymonderaymonds
S
2

I think you should achieve it using Fragment, this may helps you.

1 - in main.xml, add:

<fragment
    android:id="@+id/header"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    class="com.package.name.HeaderPanel" />

//remaining is same 

2 - the BaseActivity which extends FragmentActivity:

public class BaseActivityMenu extends FragmentActivity {

    private static final String TAG = Default.class.getName() + " - ";
    private int mResLayoutId;

    public void onCreate(Bundle savedInstanceState, int resLayout){
        super.onCreate(savedInstanceState);
        setContentView(resLayout);
        mResLayoutId = resLayout;
        switch(mResLayoutId){
            // here change with your xml file
            case R.layout.home:
                // set here common control like header textview
                break;
            default:
                break;
        }
    }
}

3 - Now, you can extend your Activity with the BaseActivity. This will allow the Activity to be extended by FragmentActivity:

public class ABCActivity extends BaseActivityMenu {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState, R.layout.home);
    }
}
Swedenborgianism answered 20/7, 2012 at 12:59 Comment(2)
Here in Base activity switch(mResLayoutId){ } is we have to give all the activities layout id's in which we want to make that header common ?Redstone
here you can set common textview like simple binding according to different layout so its depends on useSwedenborgianism
E
0

In code, your base activity is called ExampleActivity, but in your child class you are extending BaseActivityMenu. Don't know where its coming from.

Perhaps change:

public class ABCActivity extends BaseActivityMenu

To this:

public class ABCActivity extends ExampleActivity

Moreover, I would suggest you to define your base activity (ExampleActivity) as an Abstract class. For example:

public abstract class ExampleActivity extends Activity

Doing so will not define your base class as concrete and will make it easier to debug in case of problems.

Execratory answered 20/7, 2012 at 12:48 Comment(1)
It's by mistake but I am doing with the BaseActivityMenu. Now I edited thatEisenstark

© 2022 - 2024 — McMap. All rights reserved.