Search This Blog

Friday, 14 June 2013

SlidingPaneLayout Android Example : Making customize Left to right sliding panel

SlidingPaneLayout provides a horizontal, multi-pane layout for use at the top level of a UI. A left (or first) pane is treated as a content list or browser, subordinate to a primary detail view for displaying content.

SlidingPaneLayout allow user to slide the content on demand. Its very helpful while we need big screen space.
This tutorial address a very simple approach to create a SlidingPaneLayout. SlidingPaneLayout  is just like a ViewSwitcher in which first child work as sliding Panel. Look at this Layout

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/sliding_pane_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <!--
         The first child view becomes the left pane. When the combined
         desired width (expressed using android:layout_width) would
         not fit on-screen at once, the right pane is permitted to
         overlap the left. 
    -->

    <ListView
        android:id="@+id/left_pane"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="left" />
    <!--
         The second child becomes the right (content) pane. In this
         example, android:layout_weight is used to express that this
         pane should grow to consume leftover available space when the
         window is wide enough. This allows the content pane to
         responsively grow in width on larger screens while still
         requiring at least the minimum width expressed by
         android:layout_width.
    -->

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ff333333" >

        <WebView
            android:id="@+id/content_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <ProgressBar
            android:id="@+id/progressBar1"
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true" />
    </RelativeLayout>

</android.support.v4.widget.SlidingPaneLayout>

It can be easily customized. Above layout gives a simple vision that we can customize it on base of its child. Now lets have a look how Activity look a like

package com.example.android.supportv4.widget;

import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.widget.SlidingPaneLayout;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.appdata.DataUnit;
import com.example.android.supportv4.R;

public class SlidingPaneLayoutActivity extends Activity {
    private SlidingPaneLayout mSlidingLayout;
    private ListView mList;
    private WebView mContent;

    private ActionBarHelper mActionBar;

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.sliding_pane_layout);

        mSlidingLayout = (SlidingPaneLayout) findViewById(R.id.sliding_pane_layout);
        mList = (ListView) findViewById(R.id.left_pane);
        mContent = (WebView) findViewById(R.id.content_text);
        mContent.setTag(findViewById(R.id.progressBar1));
        mContent.getSettings().setJavaScriptEnabled(true);
        mSlidingLayout.setPanelSlideListener(new SliderListener());
        mSlidingLayout.openPane();

        mList.setAdapter(new ArrayAdapter<String>(this,
                R.layout.simple_list_item, DataUnit.TITLES));
        mList.setOnItemClickListener(new ListItemClickListener());

        mActionBar = createActionBarHelper();
        mActionBar.init();
        mSlidingLayout.getViewTreeObserver().addOnGlobalLayoutListener(
                new FirstLayoutListener());
    }

    @SuppressWarnings("deprecation")
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        /*
         * The action bar up action should open the slider if it is currently
         * closed, as the left pane contains content one level up in the
         * navigation hierarchy.
         */
        if (item.getItemId() == android.R.id.home && !mSlidingLayout.isOpen()) {
            mSlidingLayout.smoothSlideOpen();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * This list item click listener implements very simple view switching by
     * changing the primary content text. The slider is closed when a selection
     * is made to fully reveal the content.
     */
    private class ListItemClickListener implements ListView.OnItemClickListener {
        @SuppressWarnings("deprecation")
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                long id) {
            mContent.loadUrl(DataUnit.DIALOGUE[position]);
            mActionBar.setTitle(DataUnit.TITLES[position]);
            mSlidingLayout.smoothSlideClosed();
        }
    }

    /**
     * This panel slide listener updates the action bar accordingly for each
     * panel state.
     */
    private class SliderListener extends
            SlidingPaneLayout.SimplePanelSlideListener {
        @Override
        public void onPanelOpened(View panel) {
            mActionBar.onPanelOpened();
        }

        @Override
        public void onPanelClosed(View panel) {
            mActionBar.onPanelClosed();
        }
    }

    /**
     * This global layout listener is used to fire an event after first layout
     * occurs and then it is removed. This gives us a chance to configure parts
     * of the UI that adapt based on available space after they have had the
     * opportunity to measure and layout.
     */
    private class FirstLayoutListener implements
            ViewTreeObserver.OnGlobalLayoutListener {
        @Override
        public void onGlobalLayout() {
            mActionBar.onFirstLayout();
            mSlidingLayout.getViewTreeObserver().removeOnGlobalLayoutListener(
                    this);
        }
    }

    /**
     * Create a compatible helper that will manipulate the action bar if
     * available.
     */
    private ActionBarHelper createActionBarHelper() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            return new ActionBarHelperICS();
        } else {
            return new ActionBarHelper();
        }
    }

    /**
     * Stub action bar helper; this does nothing.
     */
    private class ActionBarHelper {
        public void init() {
        }

        public void onPanelClosed() {
        }

        public void onPanelOpened() {
        }

        public void onFirstLayout() {
        }

        public void setTitle(CharSequence title) {
        }
    }

    /**
     * Action bar helper for use on ICS and newer devices.
     */
    private class ActionBarHelperICS extends ActionBarHelper {
        private final ActionBar mActionBar;
        private CharSequence mDrawerTitle;
        private CharSequence mTitle;

        ActionBarHelperICS() {
            mActionBar = getActionBar();
        }

        @Override
        public void init() {
            mActionBar.setDisplayHomeAsUpEnabled(true);
            mActionBar.setHomeButtonEnabled(true);
            mTitle = mDrawerTitle = getTitle();
        }

        @Override
        public void onPanelClosed() {
            super.onPanelClosed();
            mActionBar.setDisplayHomeAsUpEnabled(true);
            mActionBar.setHomeButtonEnabled(true);
            mActionBar.setTitle(mTitle);
        }
        

        @Override
        public void onPanelOpened() {
            super.onPanelOpened();
            mActionBar.setHomeButtonEnabled(false);
            mActionBar.setDisplayHomeAsUpEnabled(false);
            mActionBar.setTitle(mDrawerTitle);
        }

        @SuppressWarnings("deprecation")
        @Override
        public void onFirstLayout() {
            if (mSlidingLayout.canSlide() && !mSlidingLayout.isOpen()) {
                onPanelClosed();
            } else {
                onPanelOpened();
            }
        }

        @Override
        public void setTitle(CharSequence title) {
            mTitle = title;
        }
    }

}


                                                       ScreenShot of this application




DownLoad Source Code



Saturday, 1 June 2013

Android action bar style generator

Action bar becomes popular after it launched in android 3.1 version. Using action with Fragment avoid overhead of maintaining stack of activity. But customizing action bar style is pain. We should thank to Jeff Gilfelt  for his great work. He provide tool of customizing action in unique style.
Just customize action bar style like editing a photo in Photo Editor and it will provide you complete resource with layout, style and draw-able (which include hdpi, ldpi and xhdpi images)

You can use Sherlock Action bar also if you have backward compatibility issue. You can customize its look and feel.

It provide you complete control on customization on android action bar style. you can change action bar Tab bottom line and all other thing related to it

Here Go for Action Bar Style Customization URL
Android News and source code