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.

ADB
  • 567
  • 2
  • 5
  • 20
  • Your base activity is called `ExampleActivity` but your activity extends `BaseActivityMenu`. I think you are confused. – David Wasser Jul 20 '12 at 12:48

4 Answers4

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.

Kevin Adesara
  • 3,830
  • 1
  • 17
  • 18
  • 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 stupid – ADB Jul 20 '12 at 13:12
  • don't use header.xml as your contentView, just include it in your activity_main.xml layout as part of your screen UI. – Kevin Adesara Jul 20 '12 at 13:17
  • 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.xml – Kevin Adesara Jul 20 '12 at 13:21
  • 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. – ADB Jul 20 '12 at 13:23
  • 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 */ } – Kevin Adesara Jul 20 '12 at 13:27
  • @Kevin - Can you help me out too,heres a link to my question. http://stackoverflow.com/q/23725183/1270865 – cafebabe1991 May 21 '14 at 02:32
  • @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 http://stackoverflow.com/questions/43847378/common-header-with-click-events-of-header-from-all-activities-in-xamarin-android – kumar Sudheer May 09 '17 at 05:14
  • @kumarSudheer, I've answered your question. Please check it. – Kevin Adesara Aug 03 '17 at 05:43
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.

Niko
  • 8,093
  • 5
  • 49
  • 85
  • 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 support – ADB Jul 20 '12 at 13:06
  • 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. – Niko Jul 20 '12 at 13:12
  • So what should I do in that case ? – ADB Jul 20 '12 at 13:14
  • 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. – Niko Jul 23 '12 at 04:40
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);
    }
}
Blo
  • 11,903
  • 5
  • 45
  • 99
Ankitkumar Makwana
  • 3,475
  • 3
  • 19
  • 45
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.

waqaslam
  • 67,549
  • 16
  • 165
  • 178