Android Open Source - utexas-utilities Panes Layout






From Project

Back to project page utexas-utilities.

License

The source code is released under:

Apache License

If you think the Android project utexas-utilities listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.mapsaurus.paneslayout;
//from   w  w w  . j  av  a  2  s.  c  o m
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import com.mapsaurus.paneslayout.PanesSizer.PaneSizer;

import java.util.ArrayList;

public class PanesLayout extends FrameLayout {

  /**
   * Each pane exists inside of a scroll view.
   */
  private ArrayList<SimpleScrollView> scrollers;

  /**
   * Each pane contains a container for something else (fragment, view, etc)
   */
  private ArrayList<PaneView> panes;

  /**
   * Index (index) of the currently selected index
   */
  private int currentIndex = 0;

  /**
   * Currently visible indexes. Complete means the pane is completely visible.
   */
  private int firstIndex;
  private int firstCompleteIndex;
  private int lastIndex;
  private int lastCompleteIndex;

  private int parentWidth;
  private int parentHeight;

  /**
   * Set whenever panes are changed Unset whenever index is set
   */
  private boolean panesChanged = true;

  /**
   * This object sets the size of every pane base on it's type and focus
   */
  private PaneSizer mPaneSizer;

  public void setPaneSizer(PaneSizer sizer) {
    this.mPaneSizer = sizer;
    this.requestLayout();
  }

  /**
   * Whenever the visible panes change, this is fired.
   */
  public interface OnIndexChangedListener {
    /**
     * @param firstIndex
     *            = the bottom-most visible pane
     * @param lastIndex
     *            = the top-most visible pane
     * @param firstCompleteIndex
     *            = the bottom-most completely visible pane
     * @param lastCompleteIndex
     *            = the top-most completely visible pane
     */
    public void onIndexChanged(int firstIndex, int lastIndex,
        int firstCompleteIndex, int lastCompleteIndex);
  }

  private OnIndexChangedListener mIndexChangedListener;

  public void setOnIndexChangedListener(OnIndexChangedListener l) {
    this.mIndexChangedListener = l;
  }

  public PanesLayout(Context context) {
    this(context, null);
  }

  public PanesLayout(Context context, AttributeSet attrs) {
    super(context, attrs);

    scrollers = new ArrayList<SimpleScrollView>();
    panes = new ArrayList<PaneView>();
  }

  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    parentWidth = MeasureSpec.getSize(widthMeasureSpec)
        - this.getPaddingLeft() - this.getPaddingRight();
    parentHeight = MeasureSpec.getSize(heightMeasureSpec)
        - this.getPaddingTop() - this.getPaddingBottom();
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  }

  /**
   * Inside onLayout, we might need to update the index/scroll of the panes.
   */
  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);

    if (panesChanged || changed) {
      setIndex(currentIndex);
      panesChanged = false;
    }
  }

  private int getPaneX(SimpleScrollView scroll) {
    return parentWidth - scroll.getScrollX();
  }

  private PaneView getPaneFromScroll(double x) {
    for (int i = lastIndex; i >= 0; i--) {
      SimpleScrollView scroll = scrollers.get(i);
      PaneView pane = panes.get(i);
      if (pane == null || scroll == null)
        return null;

      if (x > getPaneX(scroll))
        return pane;
    }

    return null;
  }

  private double clampIndex(double index) {
    if (index < 0)
      index = 0;
    if (index > scrollers.size() - 1)
      index = scrollers.size() - 1;
    return index;
  }

  private void scrollHelper(SimpleScrollView s, double scrollX, boolean smooth) {
    scrollX = Math.min(scrollX, parentWidth);
    scrollX = Math.max(scrollX, 0);
    
    if (smooth)
      s.smoothScrollTo((int) scrollX, 0);
    else
      s.scrollTo((int) scrollX, 0);
  }

  /**
   * Scroll all the panes based on some index. Returns which index is the
   * top-most pane.
   */
  private boolean partiallyVisible(int scroll, int width) {
    return (scroll - width < parentWidth + 5 && scroll >= 5);
  }

  private boolean completelyVisible(int scroll, int width) {
    return (scroll <= parentWidth + 5 && scroll - width >= -5);
  }

  private boolean scrollEverything(double index, boolean smooth) {
    if (parentWidth <= 0)
      return false;

    index = clampIndex(index);

    // get the top index
    int topIndex = (int) Math.ceil(index);
    if (topIndex < 0 || topIndex >= panes.size())
      return false;

    // get the minX & maxX of the top index
    PaneView topPane = panes.get(topIndex);
    SimpleScrollView topScroller = scrollers.get(topIndex);
    if (topPane == null)
      return false;

    int topWidth = topPane.containerWidth;
    double p = (topIndex - index);
    int topScroll = (int) (topWidth - topWidth * p);// + scrollOffset;

    int firstScroll = topScroll;
    for (int i = topIndex - 1; i >= 0; i--) {
      PaneView pane = panes.get(i);
      if (pane == null)
        continue;
      firstScroll += pane.containerWidth;
    }

    if (firstScroll < parentWidth)
      topScroll += parentWidth - firstScroll;

    // scroll the top pane!
    scrollHelper(topScroller, topScroll, smooth);

    int firstIndex = topIndex;
    int firstCompleteIndex = topIndex;
    int lastIndex = topIndex;
    int lastCompleteIndex = topIndex;

    int scroll = topScroll - topWidth;
    // move all panes after the top pane
    for (int i = topIndex + 1; i < panes.size(); i++) {
      SimpleScrollView scroller = scrollers.get(i);
      PaneView pane = panes.get(i);
      if (scroller == null || pane == null)
        continue;
      int width = pane.containerWidth;

      scrollHelper(scroller, scroll, smooth);

      if (partiallyVisible(scroll, width))
        lastIndex = i;
      if (completelyVisible(scroll, width))
        lastCompleteIndex = i;

      scroll -= pane.containerWidth;
    }

    scroll = topScroll;
    // move each pane before the top pane
    for (int i = topIndex - 1; i >= 0; i--) {
      SimpleScrollView scroller = scrollers.get(i);
      PaneView pane = panes.get(i);
      if (scroller == null || pane == null)
        continue;
      int width = pane.containerWidth;

      scroll += pane.containerWidth;
      scrollHelper(scroller, scroll, smooth);

      if (partiallyVisible(scroll, width))
        firstIndex = i;
      if (completelyVisible(scroll, width))
        firstCompleteIndex = i;
    }

    if (this.firstIndex != firstIndex
        || this.firstCompleteIndex != firstCompleteIndex
        || this.lastIndex != lastIndex
        || this.lastCompleteIndex != lastCompleteIndex) {
      this.firstIndex = firstIndex;
      this.firstCompleteIndex = firstCompleteIndex;
      this.lastIndex = lastIndex;
      this.lastCompleteIndex = lastCompleteIndex;
      OnIndexChangedListener l = mIndexChangedListener;
      if (l != null)
        l.onIndexChanged(firstIndex, lastIndex, firstCompleteIndex,
            lastCompleteIndex);
    }

    return true;
  }

  public void setIndex(int index) {
    index = (int) clampIndex(index);
    if (scrollEverything(index, true))
      currentIndex = lastCompleteIndex;
    else
      currentIndex = index;
  }

  public int getCurrentIndex() {
    return currentIndex;
  }

  public int getNumPanes() {
    return panes.size();
  }

  public PaneView getPane(int i) {
    if (i >= panes.size())
      return null;
    if (i < 0)
      return null;
    return panes.get(i);
  }

  public PaneView addPane(int type, boolean focused) {
    panesChanged = true;

    int index = panes.size();

    PaneView pane = new PaneView(getContext(), type, index, focused);
    panes.add(pane);

    SimpleScrollView scroller = new SimpleScrollView(getContext());
    scrollers.add(scroller);

    scroller.addView(pane);
    addView(scroller, index);

    return pane;
  }

  public ArrayList<PaneView> removePanes(int removeI) {
    panesChanged = true;

    ArrayList<PaneView> deletedPanes = new ArrayList<PaneView>();
    for (int i = scrollers.size() - 1; i >= removeI; i--) {
      if (i < 0)
        break;

      scrollers.remove(i);
      deletedPanes.add(panes.remove(i));
      removeViewAt(i);
    }

    if (removeI <= currentIndex)
      setIndex(removeI - 1);
    return deletedPanes;
  }

  private double currentX;
  private double startX;

  private double currentY;
  private double startY;
  
  private boolean dragging;

  private void onTouchEventHelper(MotionEvent event) {
    currentX = event.getX();

    if (event.getAction() == MotionEvent.ACTION_DOWN) {
      startX = currentX;
      dragging = true;
    }
  }

  @Override
  public boolean onInterceptTouchEvent(MotionEvent event) {
    onTouchEventHelper(event);

    double dx = Math.abs(currentX - startX);
    double dy = Math.abs(currentY - startY);

    if (dx > 4 * dy && dx > 10) {
      PaneView p = getPaneFromScroll(startX);

      // int bevelSize =
      // getResources().getDimensionPixelSize(R.dimen.bevel_size);

      if (p != null && p.focused == true
          && (p.index >= firstCompleteIndex && p.index <= lastCompleteIndex)) {
        return false;
      }

      return true;
    }

    return false;
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    if (!dragging)
      return true;

    onTouchEventHelper(event);

    double scroll = currentX - startX;
    double dIndex = -scroll / (parentWidth * 0.25);

    scrollEverything(currentIndex + dIndex, false);

    if ((event.getAction() == MotionEvent.ACTION_MOVE && Math.abs(dIndex) > 0.5)
        || event.getAction() == MotionEvent.ACTION_UP) {
      setIndex((int) Math.round(currentIndex + dIndex));

      dragging = false;

      if (Math.abs(dIndex) > 0.25)
        return true;
    }

    return true;
  }

  public class PaneView extends LinearLayout {

    public int containerWidth;

    public int index;
    public int type;
    public boolean focused;

    private View startPadding;
    private View leftShadow;

    private ViewGroup container;

    private View rightShadow;
    private View endPadding;

    public int getInnerId() {
      return container.getId();
    }

    public ViewGroup getInner() {
      return container;
    }

    public PaneView(Context context, int type_, int index_, boolean focused_) {
      super(context);

      focused = focused_;
      index = index_;
      type = type_;

      setOrientation(LinearLayout.HORIZONTAL);
      setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
          LayoutParams.MATCH_PARENT));

      startPadding = new View(context);
      startPadding.setVisibility(View.INVISIBLE);

      leftShadow = new View(context);
      leftShadow.setBackgroundResource(R.drawable.shadow_left);

      addView(startPadding);
      addView(leftShadow);

      container = new FrameLayout(context);
      container.setId(Integer.MAX_VALUE - index);
      container.setClickable(true);
      addView(container);

      rightShadow = new View(context);
      rightShadow.setBackgroundResource(R.drawable.shadow_right);

      endPadding = new View(context);
      endPadding.setVisibility(View.INVISIBLE);

      addView(rightShadow);
      addView(endPadding);
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      int shadowWidth = getResources().getDimensionPixelSize(
          R.dimen.shadow_size);

      startPadding.measure(MeasureSpec.makeMeasureSpec(parentWidth
          - shadowWidth, MeasureSpec.EXACTLY), MeasureSpec
          .makeMeasureSpec(parentHeight, MeasureSpec.EXACTLY));

      leftShadow.measure(MeasureSpec.makeMeasureSpec(shadowWidth,
          MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
          parentHeight, MeasureSpec.EXACTLY));

      PaneSizer paneSizer = mPaneSizer;
      if (paneSizer != null)
        containerWidth = paneSizer.getWidth(index, type, parentWidth,
            parentHeight);
      else
        containerWidth = (int) (0.7 * parentWidth);

      container.measure(MeasureSpec.makeMeasureSpec(containerWidth,
          MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
          parentHeight, MeasureSpec.EXACTLY));

      rightShadow.measure(MeasureSpec.makeMeasureSpec(shadowWidth,
          MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
          parentHeight, MeasureSpec.EXACTLY));

      endPadding.measure(MeasureSpec.makeMeasureSpec(parentWidth
          - containerWidth - shadowWidth, MeasureSpec.EXACTLY),
          MeasureSpec.makeMeasureSpec(parentHeight,
              MeasureSpec.EXACTLY));

      this.setMeasuredDimension(
          resolveSize(parentWidth * 2, widthMeasureSpec),
          resolveSize(parentHeight, heightMeasureSpec));
    }
  }

  public boolean onBackPressed() {
    int oldIndex = currentIndex;
    setIndex(currentIndex - 1);

    if (oldIndex != currentIndex)
      return true;
    return false;
  }

}




Java Source Code List

com.google.maps.android.ui.MyIconGenerator.java
com.mapsaurus.paneslayout.ActivityDelegate.java
com.mapsaurus.paneslayout.FragmentLauncher.java
com.mapsaurus.paneslayout.MenuItemWrapper.java
com.mapsaurus.paneslayout.MySlidingPaneLayout.java
com.mapsaurus.paneslayout.PanesActivity.java
com.mapsaurus.paneslayout.PanesLayout.java
com.mapsaurus.paneslayout.PanesSizer.java
com.mapsaurus.paneslayout.PhoneDelegate.java
com.mapsaurus.paneslayout.SimpleScrollView.java
com.mapsaurus.paneslayout.TabletDelegate.java
com.nasageek.utexasutilities.AsyncTask.java
com.nasageek.utexasutilities.AttachmentDownloadService.java
com.nasageek.utexasutilities.AuthCookie.java
com.nasageek.utexasutilities.BlackboardDashboardXmlParser.java
com.nasageek.utexasutilities.BuildingDatabase.java
com.nasageek.utexasutilities.BuildingProvider.java
com.nasageek.utexasutilities.BuildingSaxHandler.java
com.nasageek.utexasutilities.ChangeLog.java
com.nasageek.utexasutilities.ChangeableContextTask.java
com.nasageek.utexasutilities.CourseMapSaxHandler.java
com.nasageek.utexasutilities.FixedListPreference.java
com.nasageek.utexasutilities.LoginWebViewClient.java
com.nasageek.utexasutilities.MarkerManager.java
com.nasageek.utexasutilities.MyPair.java
com.nasageek.utexasutilities.MyScrollView.java
com.nasageek.utexasutilities.PlacemarkSaxHandler.java
com.nasageek.utexasutilities.PnaAuthCookie.java
com.nasageek.utexasutilities.RouteSaxHandler.java
com.nasageek.utexasutilities.SecurePreferences.java
com.nasageek.utexasutilities.TempLoginException.java
com.nasageek.utexasutilities.UTilitiesApplication.java
com.nasageek.utexasutilities.UtdAuthCookie.java
com.nasageek.utexasutilities.Utility.java
com.nasageek.utexasutilities.WrappedViewPager.java
com.nasageek.utexasutilities.WrappingSlidingDrawer.java
com.nasageek.utexasutilities.activities.AboutMeActivity.java
com.nasageek.utexasutilities.activities.BalanceActivity.java
com.nasageek.utexasutilities.activities.BlackboardPanesActivity.java
com.nasageek.utexasutilities.activities.CampusMapActivity.java
com.nasageek.utexasutilities.activities.DataUsageActivity.java
com.nasageek.utexasutilities.activities.LoginActivity.java
com.nasageek.utexasutilities.activities.MenuActivity.java
com.nasageek.utexasutilities.activities.NutritionInfoActivity.java
com.nasageek.utexasutilities.activities.Preferences.java
com.nasageek.utexasutilities.activities.ScheduleActivity.java
com.nasageek.utexasutilities.activities.UTilitiesActivity.java
com.nasageek.utexasutilities.adapters.BBClassAdapter.java
com.nasageek.utexasutilities.adapters.CourseMapAdapter.java
com.nasageek.utexasutilities.adapters.MultiPanePagerAdapter.java
com.nasageek.utexasutilities.adapters.MyFragmentPagerAdapter.java
com.nasageek.utexasutilities.adapters.ScheduleClassAdapter.java
com.nasageek.utexasutilities.adapters.TransactionAdapter.java
com.nasageek.utexasutilities.fragments.ActionModeFragment.java
com.nasageek.utexasutilities.fragments.BlackboardAnnouncementsFragment.java
com.nasageek.utexasutilities.fragments.BlackboardCourseListFragment.java
com.nasageek.utexasutilities.fragments.BlackboardCourseMapFragment.java
com.nasageek.utexasutilities.fragments.BlackboardDashboardFragment.java
com.nasageek.utexasutilities.fragments.BlackboardDownloadableItemFragment.java
com.nasageek.utexasutilities.fragments.BlackboardExternalItemFragment.java
com.nasageek.utexasutilities.fragments.BlackboardFragment.java
com.nasageek.utexasutilities.fragments.BlackboardGradesFragment.java
com.nasageek.utexasutilities.fragments.BlackboardPagerFragment.java
com.nasageek.utexasutilities.fragments.CourseScheduleFragment.java
com.nasageek.utexasutilities.fragments.DatePickerFragment.java
com.nasageek.utexasutilities.fragments.DoubleDatePickerDialogFragment.java
com.nasageek.utexasutilities.fragments.ExamScheduleFragment.java
com.nasageek.utexasutilities.fragments.MenuFragment.java
com.nasageek.utexasutilities.fragments.NutritionInfoFragment.java
com.nasageek.utexasutilities.fragments.PickCalendarDialogFragment.java
com.nasageek.utexasutilities.fragments.TransactionsFragment.java
com.nasageek.utexasutilities.model.BBClass.java
com.nasageek.utexasutilities.model.Building.java
com.nasageek.utexasutilities.model.Classtime.java
com.nasageek.utexasutilities.model.CourseMapItem.java
com.nasageek.utexasutilities.model.FeedItem.java
com.nasageek.utexasutilities.model.Placemark.java
com.nasageek.utexasutilities.model.Transaction.java
com.nasageek.utexasutilities.model.UTClass.java
com.viewpagerindicator.MyTabPageIndicator.java