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



4 comments:

  1. Nice Post, very few site contains information about SlidingPaneLayout. thank you very much

    ReplyDelete
  2. I am trying to download the file but the downloaded file is an installer...please check ziddu link....it might have virus

    ReplyDelete
  3. Nice post.. very useful... Thank you!
    I want the SlidingPaneLayout to be fixed in landscape mode, i.e. left and right panes both should be visible together...... How can this be achieved?

    ReplyDelete
  4. I did not get your problem correctly, But you make SlidingPanel in Landscape Mode also without any issue. Look at the XML layout above in the Tutorial , Sliding Panel is just combination of views. So you can customize it easily.

    ReplyDelete

Feedback always help in improvement. If you have any query suggestion feel free to comment and Keep visiting my blog to encourage me to blogging

Android News and source code