简体   繁体   中英

SlidingDrawer semi opened on start

I am working a piece of my app and I was wondering if it's possible to have a Sliding Drawer open partially instead of being fully closed so the user can peak at the text content before clicking the show more button which would be able to show the rest of the text.

Thanks in advance.

I had a similar problem and I ended up modifying SlidingDrawer to be able to show a part of the content when the Drawer is collapsed/closed. With SemiClosedSlidingDrawer you specify how much of the content screen that should be shown in collapsed/closed mode with the dimension attribute 'semiClosedContentSize':

<se.smartrefill.view.SemiClosedSlidingDrawer 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:custom="http://schemas.android.com/apk/res/se.smartrefill.app.x"
    android:id="@+id/mySlidingDrawer"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    custom:orientation="horizontal"
    custom:handle="@+id/handle"
    custom:content="@+id/content"
    custom:allowSingleTap="true"
    custom:semiClosedContentSize="40dp"
    >

Then your attrs.xml (in res/values/) also needs to contain:

<declare-styleable name="SemiClosedSlidingDrawer">
    <attr name="handle" format="integer"/>
    <attr name="content" format="integer"/>
    <attr name="orientation" format="string" />
    <attr name="bottomOffset" format="dimension"  />
    <attr name="topOffset" format="dimension"  />
    <attr name="allowSingleTap" format="boolean" />
    <attr name="animateOnClick" format="boolean" />
    <attr name="semiClosedContentSize" format="dimension" />
</declare-styleable>

, where 'se.smartrefill.app.x' refers to the application package defined in the AndroidManifest.

This specific SlidingDrawer (above) is configured to use horizontal orientation, and a 40dp wide (and fill_parent high) strip of the content view will be shown (to the right) in collapsed/closed mode. In expanded/open mode, this implementation will work just as the standard SlidingDrawer, but in collapsed/closed mode the content screen will never become completely hidden (unless you specify semiClosedContentSize="0dp", which will turn it into a standard SlidingDrawer). This implementation is based on the implementation of SlidingDrawer in Android-4 ("1.6"), but is compatible up to (incl.) Android-14 ("4.0"). This implementation ought to be compatible with future versions of Android as well (almost nothing has changed in SlidingDrawer between API 4 and API 14). This implementation supports both vertical and horizontal orientation.

Try it out!

Regards, Jacob

I came across a similar problem as you. At the start I only need a (rather narrow) list view in my sliding drawer, so that the user can just have a peak into the content. The drawer should fully open only when an item on the list is selected and some content for that item is displayed in an image view next to the list view.

Therefore my drawer's layout is like that:

<RelativeLayout
  android:id="@+id/drawerContainer"
  android:layout_alignParentRight="true"
  android:layout_width="120dp"
  android:layout_height="match_parent">
  <SlidingDrawer
    android:id="@+id/drawer"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:handle="@+id/handle"
    android:content="@+id/content">
    <ImageView
      android:id="@+id/handle"
      android:layout_width="20dip"
      android:layout_height="match_parent"
      android:src="@drawable/drawer_handle />
    <LinearLayout
      android:id="@+id/content"
      android:layout_width="wrap_content"
      android:layout_height="match_parent"
      android:orientation="horizontal">
      <ListView
        android:id="@+id/list"
        android:layout_width="100dp"
        android:layout_height="match_parent">
      </ListView>
      <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone">
      </ImageView>
    </LinearLayout>
  </SlidingDrawer> 
</RelativeLayout>

So at the start the image view is gone. In the OnItemClickListener for my list view I control the layout parameters of the drawer:

private OnItemClickListener onItemClickListener = new OnItemClickListener() {

  @Override
  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {     

    if (imageView.getVisibility() == View.GONE) {     
      ExpandViewAnimation animation = new ExpandViewAnimation(drawerContainer, ((View) drawerContainer.getParent()).getWidth());
      animation.setDuration(500);
      drawerContainer.setAnimation(animation);
      animation.start();
      imageView.setVisibility(View.VISIBLE);
    }
    //code for displaying an image in the imageview
  }  
};

As you can see I'm using my custom animation for the drawer container so that the nicity of the opening sliding drawer is preserved. Here's the animation class:

public class ExpandViewAnimation extends Animation {
  int targetWidth;
  int initialWidth;
  View view;

  public ExpandViewAnimation(View view, int targetWidth) {
    this.view = view;
    this.targetWidth = targetWidth;
    initialWidth = view.getWidth();
  }

  @Override
  protected void applyTransformation(float interpolatedTime, Transformation t) {

    int newWidth = initialWidth + (int) ((targetWidth - initialWidth) * interpolatedTime);

    LayoutParams lp = new LayoutParams((LayoutParams) view.getLayoutParams());
    lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    view.setLayoutParams(lp);

    view.getLayoutParams().width = newWidth;
    view.requestLayout();

    if (newWidth == targetWidth) {
      LayoutParams matchParentParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
      view.setLayoutParams(matchParentParams);
      view.clearAnimation();
    }
  }

  @Override
  public void initialize(int width, int height, int parentWidth, int parentHeight) {
    super.initialize(width, height, parentWidth, parentHeight);
  }

  @Override
  public boolean willChangeBounds() {
    return true;
  }
}

The reason why I am setting new layout parameters is because at the start I'm saving the initial set of parameters (as in the layout file) and apply it back in onDrawerClose:

private OnDrawerCloseListener onDrawerCloseListener = new OnDrawerCloseListener() {

  @Override
  public void onDrawerClosed() {
    imageView.setVisibility(View.GONE);
    imageView.setImageDrawable(null);  
    drawerContainer.setLayoutParams(initialLayoutParams);  
  }
};

If you want the user to be able to fully open the drawer with the swipe move on the handle, you can apply a similar animation in onTouchListener.

The final remark: my sliding drawer is in a layout because it's included into that layout with so that the drawer is accessible in several places. In general you don't need that layout around your drawer.

Maybe try something like setting the innner content of the of the slidingdrawer be something like

 <SlidingDrawer android:layout_height="wrap_content"
             android:handle="@+id/handle" 
             android:content="@+id/content"
             android:id="@+id/slide" 
             android:orientation="vertical"
             android:layout_width="fill_parent">
    <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"...>
       <Button android:id="@+id/ShowMore"... />
       <LinearLayout android:id="@+id/More" android:visibility="gone" ...>
           ... more stuff
       </LinearLayout>

    </LinearLayout>
</SlidingDrawer>

then set the button ShowMore to toggle the visibility of the linearlayout "More" between View.GONE and View.VISIBLE

**EDIT: Hmm re-reading your question, I'm actually a little confused: the title is "..opened on start", but then you say "open partially". Did you want it to start in the partially opened state? or open partially when the user drags it? My proposal (untested), is to have the sliding drawer wrap its size to the content, and have the content initially start small showing just the button + whatever you want to show outside the "More" inner linear layout, then show that when they click the button.

I recently developed app in which i had requirement as that of required by you. By googling I found that We have modify source code of original Sliding Drawer I did that and and whole modified code is with me I had tested and its working fine. I can send you whole file.Just give me your Email-id.
you also require attrs.xml in your values folder of your project where you want to use this code. attrs.xml code is posted below.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="SlidingDrawer">
        <attr name="handle" format="integer"/>
        <attr name="content" format="integer"/>
    </declare-styleable>
</resources>

I hope this will help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM