Thursday 25 May 2017

How to add a common header across all activities using Parent-Child Relationship

This blog post demonstrates how to add a common header layout in all our Android Activities using simple Parent-Child Relationship.

Note : you can add Fragments as well in the container i am using in the parent class to have one activity and multiple fragments as per your app architecture.

My use case was to implement a common header in an existing project with 50+ activities which shows a to line header with a message whether a user is online or offline without changing to much in the existing code.  


1. BaseActivity.java


package kamal.com.headtest;

import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class BaseActivity extends AppCompatActivity {

    private TextView tvHeader,tvClose;
    private FrameLayout activityContainer;
    private RelativeLayout rlHeaderView;

    @Override
    public void setContentView(int layoutResID) {
        LinearLayout llparentView = (LinearLayout) getLayoutInflater().inflate(R.layout.activity_main, null);
        initViews(llparentView);
        getLayoutInflater().inflate(layoutResID, activityContainer, true);
        super.setContentView(llparentView);
    }

    /**
     *  Initialize BaseActivity Views
     * @param view : parent use to initialize child views
     */
    private void initViews(View view){
        tvHeader=(TextView)view.findViewById(R.id.headertext);
        tvClose=(TextView)view.findViewById(R.id.closebtn);
        activityContainer = (FrameLayout) view.findViewById(R.id.activity_content);
        rlHeaderView=(RelativeLayout)view.findViewById(R.id.headerviewrl);
        tvClose.setOnClickListener(closeBtnListener);
    }


    /**
     *  anonymous onclicklistener to handle a click event for Close button in header.
     */
    private View.OnClickListener closeBtnListener=new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            finish();
        }
    };

    /**
     *  Method to be overiden by child classes if need to hide header view
     * @param show : true or false as to handle visibility of the header
     */
    public void showHeader(boolean show){
        rlHeaderView.setVisibility(show ? View.VISIBLE : View.GONE);
    }

    /**
     *  Method to be overiden by child classes if need to hide header view
     * @param value : of the header
     */
    public void setHeaderText(String value){
        tvHeader.setText(value);
    }
}


2. ChildActivity.java

package kamal.com.headtest;
import android.os.Bundle;
import android.support.annotation.Nullable;

public class ChildActivity extends BaseActivity{

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.childlayout);
        showHeader(true);;
    }
}

3. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/parent_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/headerviewrl"
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:layout_height="?actionBarSize">

        <TextView
            android:id="@+id/headertext"
            android:layout_width="wrap_content"
            android:layout_height="?actionBarSize"
            android:layout_centerHorizontal="true"
            android:gravity="center"
            android:padding="10dp"
            android:textSize="20sp"
            android:textStyle="bold"
            android:text="My Header View" />

        <TextView
            android:id="@+id/closebtn"
            android:layout_width="wrap_content"
            android:layout_height="?actionBarSize"
            android:gravity="center"
            android:padding="10dp"
            android:textSize="30sp"
            android:textStyle="bold"
            android:layout_alignParentRight="true"
            android:text="X" />

    </RelativeLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#000000"
        />

    <FrameLayout
        android:id="@+id/activity_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>


4. childlayout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_marginTop="10dp"
        android:layout_centerHorizontal="true"
        android:text="Testing child" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_marginTop="10dp"
        android:layout_centerHorizontal="true"
        android:text="Testing child" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_marginTop="10dp"
        android:layout_centerHorizontal="true"
        android:text="Testing child" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_marginTop="10dp"
        android:layout_centerHorizontal="true"
        android:text="Testing child" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_marginTop="10dp"
        android:layout_centerHorizontal="true"
        android:text="Testing child" />

</LinearLayout>


5. manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="kamal.com.headtest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".ChildActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>



Output:





Cheers :-)

No comments:

Post a Comment