【问题标题】:android - creating something like a vertical viewpagerandroid - 创建类似垂直viewpager的东西
【发布时间】:2014-11-30 18:51:09
【问题描述】:

我想实现这样的目标

我已经用列表视图做了类似的事情,但我遇到的问题是,在我选择一个项目后,它不会具有按下时的颜色。 还有一个视图寻呼机,我会有一个额外的容器来放置我的片段。

如果这样的事情能奏效,那就更好了!

Android: Vertical ViewPager 我读过这个,看起来不错,但我也想在屏幕左侧有一些项目。

您认为最好的方法是什么? 而且,我已经有一个导航抽屉,所以新的不是办法。

【问题讨论】:

    标签: android android-viewpager vertical-alignment


    【解决方案1】:

    我已经用列表视图做了类似的事情,但问题是我 有的是我选择一个项目后,它不会有它的颜色 按下时。

    这很容易解决。在 onClick(View arg0) 方法中添加 arg0.setSelected(true)。还要记得将旧视图的选中状态设置为 false。

    如果存在视图被重复使用的风险,您需要通过将数据列表更改为地图并在条目中存储布尔值来跟踪选择了哪个视图。但是,如果您想将列表和详细片段一起滚动,或者列表足够短,就像您的图片一样,则没有必要。

    将背景颜色更改为选择器(可绘制的 xml)

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android" >
        <item
            android:color="@color/selected_color_resource"
            android:state_selected="true" />
        <item
            android:color="@color/color_resource" />  <!-- default -->
    </selector>
    

    将使用第一个匹配状态,因此请确保默认为最后一项。

    还有一个视图寻呼机我会有一个额外的容器 可以放我的碎片。

    是的,使用 Brett 的解决方案。用 VerticalViewPager 替换您的详细片段。您需要将您的活动(或处理您的列表的任何类)设置为 ViewPager.SimpleOnPageChangeListener。这样当有人滚动选定的列表项时可以更改。多亏了这个好方法,你可以做很多很酷的动画

    onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
    

    【讨论】:

      【解决方案2】:

      试试下面的例子,

      main.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">
          <com.brandontate.BTGridPager.BTFragmentGridPager
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:id="@+id/fragmentGridPager"
                  android:background="#ffff00"/>
      
      </LinearLayout>
      

      demo_fragment.xml

      <?xml version="1.0" encoding="utf-8"?>
      
      <RelativeLayout 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:layout_gravity="center_vertical|center_horizontal"
                  android:id="@+id/label"
                  android:textSize="45sp"
                  android:textColor="@android:color/black"
                  android:layout_centerInParent="true"
                  />
      
      </RelativeLayout>
      

      DemoFragment.java

      package com.demo.app;
      
      import android.os.Bundle;
      import android.support.v4.app.Fragment;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;
      import android.widget.RelativeLayout;
      import android.widget.TextView;
      import com.brandontate.BTGridPager.BTFragmentGridPager;
      import com.example.BTGridPager.R;
      
      /**
       * BTGridPager
       *
       * @author Brandon Tate
       */
      public class DemoFragment extends Fragment {
      
          TextView mLabel;
      
          BTFragmentGridPager.GridIndex mGridIndex;
      
      
          public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
      
              RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.demo_fragment, container, false);
              mLabel = (TextView) layout.findViewById(R.id.label);
              setTxtRow(mGridIndex);
      
              return layout;
      
          }
      
      
          public void setTxtRow(BTFragmentGridPager.GridIndex gridIndex) {
              mLabel.setText("(" + gridIndex.getRow() + ", " + gridIndex.getCol() + ")");
          }
      
          public void setGridIndex(BTFragmentGridPager.GridIndex gridIndex){
              mGridIndex = gridIndex;
          }
      
      }
      

      Demo.java

      package com.demo.app;
      
      import android.os.Bundle;
      import android.support.v4.app.Fragment;
      import android.support.v4.app.FragmentActivity;
      import android.util.Log;
      import com.brandontate.BTGridPager.BTFragmentGridPager;
      import com.example.BTGridPager.R;
      
      public class Demo extends FragmentActivity {
      
          private BTFragmentGridPager.FragmentGridPagerAdapter mFragmentGridPagerAdapter;
      
          /**
           * Called when the activity is first created.
           */
          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.main);
      
              final BTFragmentGridPager mFragmentGridPager = (BTFragmentGridPager) findViewById(R.id.fragmentGridPager);
      
              mFragmentGridPagerAdapter = new BTFragmentGridPager.FragmentGridPagerAdapter() {
                  @Override
                  public int rowCount() {
                      return 10;
                  }
      
                  @Override
                  public int columnCount(int row) {
                      return 10;
                  }
      
                  @Override
                  public Fragment getItem(BTFragmentGridPager.GridIndex index) {
                      DemoFragment panelFrag1 = new DemoFragment();
                      panelFrag1.setGridIndex(index);
      
                      return panelFrag1;
                  }
              };
      
              mFragmentGridPager.setGridPagerAdapter(mFragmentGridPagerAdapter);
          }
      }
      

      BTVerticalPagerFragment.java

      package com.brandontate.BTGridPager;
      
      import android.os.Bundle;
      import android.support.v4.app.Fragment;
      import android.support.v4.app.FragmentStatePagerAdapter;
      import android.support.v4.view.ViewPager;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;
      import android.widget.LinearLayout;
      
      /**
       * BTGridPager
       *
       * @author Brandon Tate
       */
      public class BTVerticalPagerFragment extends Fragment {
      
          /** Pager adapter. */
          private FragmentStatePagerAdapter mVerticalPagerAdapter;
      
          /** Page change listener. */
          private ViewPager.OnPageChangeListener mPageChangeListener;
      
          /** The actual pager. */
          private BTVerticalPager mPager;
      
          /** The start page when the pager is loaded. */
          private int mStartPage = 0;
      
          private BTFragmentGridPager mGridPager;
      
          public BTVerticalPagerFragment(){
      
          }
      
      //    public BTVerticalPagerFragment (BTFragmentGridPager gridPager) {
      //
      //        mGridPager = gridPager;
      //    }
      
      
      
          @Override
          public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      
              LinearLayout view = new LinearLayout(getActivity());
              view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
              view.setId(1);
      
              if (mGridPager != null) {
                  mPager = new BTVerticalPager(getActivity(), mGridPager);
                  mPager.setId(2);
                  mPager.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
                  mPager.setAdapter(mVerticalPagerAdapter);
                  mPager.setCurrentItem(mStartPage);
                  mPager.setOnPageChangeListener(mPageChangeListener);
      
                  view.addView(mPager);
              }
      
              return view;
          }
      
          public FragmentStatePagerAdapter getVerticalPagerAdapter() {
              return mVerticalPagerAdapter;
          }
      
          public void setGridPager(BTFragmentGridPager gridPager){
              mGridPager = gridPager;
          }
      
          public void setVerticalPagerAdapter(FragmentStatePagerAdapter verticalPagerAdapter) {
              this.mVerticalPagerAdapter = verticalPagerAdapter;
      
              if (mPager != null)
                  mPager.setAdapter(mVerticalPagerAdapter);
          }
      
          public void setPageChangeListener(ViewPager.OnPageChangeListener pageChangeListener) {
              this.mPageChangeListener = pageChangeListener;
      
              if (mPager != null)
                  mPager.setOnPageChangeListener(mPageChangeListener);
          }
      
          public BTVerticalPager getPager() {
              return mPager;
          }
      
          public void setStartPage(int startPage) {
              this.mStartPage = startPage;
          }
      
      }
      

      BTVerticalPager.java

      package com.brandontate.BTGridPager;
      
      
      import android.content.Context;
      import android.support.v4.view.ViewPager;
      import android.util.AttributeSet;
      import android.view.MotionEvent;
      import android.view.View;
      
      /**
       * BTGridPager
       *
       * @author Brandon Tate
       */
      public class BTVerticalPager extends ViewPager {
      
          BTFragmentGridPager mGridPager;
      
          public BTVerticalPager(Context context, BTFragmentGridPager gridPager) {
              super(context);
              init();
      
              mGridPager = gridPager;
          }
      
          public BTVerticalPager(Context context, AttributeSet attrs, BTFragmentGridPager gridPager) {
              super(context, attrs);
              init();
      
              mGridPager = gridPager;
          }
      
          private void init(){
      
              // The majority of the magic happens here
              setPageTransformer(true, new VerticalPageTransformer());
              // The easiest way to get rid of the overscroll drawing that happens on the left and right
              setOverScrollMode(OVER_SCROLL_NEVER);
          }
      
          @Override
          protected void onPageScrolled(int position, float offset, int offsetPixels) {
              super.onPageScrolled(position, offset, offsetPixels);
      
              if (offset == 0  && mGridPager.shouldReset) {
                  getRootView().post(new Runnable() {
                      @Override
                      public void run() {
                          mGridPager.shouldReset = false;
                          mGridPager.resetAdapter();
                      }
                  });
              }
          }
      
          private class VerticalPageTransformer implements ViewPager.PageTransformer {
      
              @Override
              public void transformPage(View view, float position) {
                  int pageWidth = view.getWidth();
                  int pageHeight = view.getHeight();
      
                  view.setAlpha(1);
      //
      //            if (position < -1 && !mGridPager.shouldReset) { // [-Infinity,-1)
      //                // This page is way off-screen to the left.
      //                view.setAlpha(0);
      //
      //            }
                  if (position >= -1 && position <= 1) { // [-1,1]
                      // Counteract the default slide transition
                      view.setTranslationX(pageWidth * -position);
      
                      //set Y position to swipe in from top
                      float yPosition = position * pageHeight;
                      view.setTranslationY(yPosition);
                  }
      //            } else if (!mGridPager.shouldReset) { // (1,+Infinity]
      //                // This page is way off-screen to the right.
      //                view.setAlpha(0);
      //            }
              }
          }
      
          /**
           * Swaps the X and Y coordinates of your touch event
           */
          @Override
          public boolean onTouchEvent(MotionEvent ev) {
              //swap the x and y coords of the touch event
              ev.setLocation(ev.getY(), ev.getX());
      
              return super.onTouchEvent(ev);
          }
      }
      

      BTFragmentGridPager.java

      package com.brandontate.BTGridPager;
      
      
      import android.content.Context;
      import android.support.v4.app.Fragment;
      import android.support.v4.app.FragmentActivity;
      import android.support.v4.app.FragmentManager;
      import android.support.v4.app.FragmentStatePagerAdapter;
      import android.support.v4.view.ViewPager;
      import android.util.AttributeSet;
      import android.view.View;
      
      
      /**
       * BTGridPager
       *
       * The grid pager works by maintaining a view port that moves around a virtual grid.  The views to show in this viewport will be provided by the BTGridPagerAdapter.
       * When the a new page is selected the view port is updated to hold only the views surrounding it.
       *
       * @author Brandon Tate
       */
      public class BTFragmentGridPager extends ViewPager {
      
          /** Bit flag for no wrapping. */
          public static final int GRID_WRAP_NONE = 0;
      
          /** Bit flag for left side wrapping. */
          public static final int GRID_WRAP_LEFT = 1 << 1;
      
          /** Bit flag for right side wrapping. */
          public static final int GRID_WRAP_RIGHT = 1 << 2;
      
          /** Bit flag for top side wrapping. */
          public static final int GRID_WRAP_UP = 1 << 3;
      
          /** Bit flag for bottom side wrapping. */
          public static final int GRID_WRAP_DOWN = 1 << 4;
      
          /** Wrapping flag. */
          private int mWrappingFlags = (GRID_WRAP_DOWN | GRID_WRAP_UP | GRID_WRAP_RIGHT);
      
          /** Bit flag for no resets. */
          public static final int GRID_RESET_NONE = 0;
      
          /** Bit flag for resetting to first column on row change. */
          public static final int GRID_RESET_ROW = 1 << 1;
      
          /** Bit flag for resetting to first row on column change. */
          public static final int GRID_RESET_COL = 1 << 2;
      
          /** Reset Flag. */
          private int mResetFlags = GRID_RESET_NONE;
      
      
          /** Current grid index. */
          public GridIndex mCurrentIndex = new GridIndex(0, 0);
      
          /** The fragment grid pager adapter for retrieving views. */
          private FragmentGridPagerAdapter mGridPagerAdapter;
      
          /** How many views to load on each side of the central view. */
          private int mGridPadding = 1;
      
          boolean shouldReset = false;
      
          public BTFragmentGridPager(Context context) {
              super(context);
              init();
          }
      
      
          /**
           * Used to inflate the Workspace from XML.
           *
           * @param context
           *            The application's context.
           * @param attrs
           *            The attribtues set containing the Workspace's customization values.
           */
          public BTFragmentGridPager(Context context, AttributeSet attrs) {
              super(context, attrs);
              init();
          }
      
          public void init(){
              resetAdapter();
          }
      
          //*****************************************************
          //*
          //*         Helpers
          //*
          //*****************************************************
      
          private boolean canScrollLeft(){
              return  mGridPagerAdapter != null && !(mCurrentIndex.getCol() == 0 && (0 == (mWrappingFlags & GRID_WRAP_LEFT)));
          }
      
          private boolean canScrollRight(){
              return mGridPagerAdapter != null && !(mCurrentIndex.getCol() == (mGridPagerAdapter.columnCount(mCurrentIndex.getRow()) - 1) && (0 == (mWrappingFlags & GRID_WRAP_RIGHT)));
          }
      
          private boolean canScrollUp(){
              return  mGridPagerAdapter != null && !(mCurrentIndex.getRow() == 0 && (0 == (mWrappingFlags & GRID_WRAP_UP)));
          }
      
          private boolean canScrollDown(){
              return  mGridPagerAdapter != null && !(mCurrentIndex.getRow() == (mGridPagerAdapter.rowCount() - 1) && (0 == (mWrappingFlags & GRID_WRAP_DOWN)));
          }
      
          private GridIndex wrapGridIndex(GridIndex index){
      
              int newRow = index.getRow();
      
              if (newRow < 0)
                  newRow = mGridPagerAdapter.rowCount() + newRow;
              else if(newRow >= mGridPagerAdapter.rowCount())
                  newRow = (mGridPagerAdapter.rowCount() - newRow);
      
              int newCol = index.getCol();
      
              if (newCol < 0)
                  newCol = mGridPagerAdapter.columnCount(newRow) + newCol;
              else if (newCol >= mGridPagerAdapter.columnCount(newRow))
                  newCol = (mGridPagerAdapter.columnCount(newRow) - newCol);
      
              return new GridIndex(newRow, newCol);
          }
      
          /**
           *   Completely resets the adapter with updated current grid index.
           *
           *   No access modifier -- package-private
           */
          void resetAdapter(){
      
              // Clear old on page change listener to avoid unwanted actions
              setOnPageChangeListener(null);
      
              setAdapter(new FragmentGridHorizontalPagerAdapter(((FragmentActivity) getContext()).getSupportFragmentManager(), this));
      
              if (!canScrollLeft())
                  setCurrentItem(0, false);
              else if(!canScrollRight())
                  setCurrentItem(getAdapter().getCount() - 1);
              else
                  setCurrentItem(mGridPadding, false);
      
              setOnPageChangeListener(new SimpleOnPageChangeListener(){
      
                  @Override
                  public void onPageSelected(int i) {
      
                      // Default to wrapping index
                      int newCol = mCurrentIndex.getCol() + ( -1 * (mGridPadding - i) );
      
                      // Adjust for limited wrapping
                      if (!canScrollLeft())
                          newCol = mCurrentIndex.getCol() + i;
                      else if(!canScrollRight())
                          newCol--;
      
                      mCurrentIndex = wrapGridIndex( new GridIndex( (0 != (mResetFlags & GRID_RESET_COL) ) ? 0 : mCurrentIndex.getRow() ,  newCol) );
      
                      shouldReset = true;
                  }
              });
          }
      
          @Override
          protected void onPageScrolled(int position, float offset, int offsetPixels) {
              super.onPageScrolled(position, offset, offsetPixels);
      
              if (offset == 0 && shouldReset) {
                  getRootView().post(new Runnable() {
                      @Override
                      public void run() {
                          shouldReset = false;
                          resetAdapter();
                      }
                  });
      
              }
          }
      
          @Override
          protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
              return false;
          }
      
          //*****************************************************
          //*
          //*         Getters/Setters
          //*
          //*****************************************************
      
          public FragmentGridPagerAdapter getGridPagerAdapter() {
              return mGridPagerAdapter;
          }
      
          public void setGridPagerAdapter(FragmentGridPagerAdapter gridPagerAdapter) {
              this.mGridPagerAdapter = gridPagerAdapter;
              resetAdapter();
          }
      
          public int getResetFlags() {
              return mResetFlags;
          }
      
          public void setResetFlags(int resetFlags) {
              this.mResetFlags = resetFlags;
          }
      
          public int getWrappingFlags() {
              return mWrappingFlags;
          }
      
          public void setWrappingFlags(int wrappingFlags) {
              this.mWrappingFlags = wrappingFlags;
          }
      
      
          //*****************************************************
          //*
          //*         Adapters
          //*
          //*****************************************************
      
          public class FragmentGridHorizontalPagerAdapter extends FragmentStatePagerAdapter{
      
              FragmentManager fm;
              BTFragmentGridPager mGridPager;
      
              public FragmentGridHorizontalPagerAdapter(FragmentManager fm, BTFragmentGridPager gridPager) {
                  super(fm);
      
                  this.fm = fm;
                  this.mGridPager = gridPager;
              }
      
              @Override
              public Fragment getItem(int i) {
      
                  if (mGridPagerAdapter == null)
                      return new Fragment();
      
                  // Figure out if this is our vertical pager
                  boolean vpFragFlag = false;
      
                  if (!canScrollLeft() &&  i == 0)
                      vpFragFlag = true;
                  else if(!canScrollRight() && i == (getAdapter().getCount() - 1))
                      vpFragFlag = true;
                  else if(canScrollLeft() && canScrollRight())
                      vpFragFlag = (i == mGridPadding);
      
                  if (vpFragFlag){
      
                      BTVerticalPagerFragment vpFragment = new BTVerticalPagerFragment();
                      vpFragment.setGridPager(mGridPager);
      
                      vpFragment.setVerticalPagerAdapter(new FragmentStatePagerAdapter(fm){
                          @Override
                          public Fragment getItem(int i) {
      
                              if (mGridPagerAdapter == null)
                                  return new Fragment();
      
                              int newCol = mCurrentIndex.getCol();
      
                              // If it's not the middle one and we need a row reset
                              if (i != mGridPadding && (0 != (mResetFlags & GRID_RESET_ROW) ))
                                  newCol = 0;
      
      
                              // Default my view index wrapped
                              GridIndex viewIndex = wrapGridIndex(wrapGridIndex( new GridIndex( mCurrentIndex.getRow() + ( -1 * (mGridPadding - i) ), newCol ) ) );
      
                              // Adjust for limited wrapping
                              if (!canScrollUp() || !canScrollDown()) {
                                  if (i == this.getCount() - 1)
                                      viewIndex.setRow(mGridPagerAdapter.rowCount() - 1);
                                  else
                                      viewIndex.setRow(mCurrentIndex.getRow() + i);
                              }
      
                              return mGridPagerAdapter.getItem(viewIndex);
                          }
      
                          @Override
                          public int getCount() {
                              return (mGridPadding * 2) + 1;
                          }
      
                          public int getItemPosition(Object object){
                              return POSITION_NONE;
                          }
                      });
      
      
                      if (!canScrollUp())
                          vpFragment.setStartPage(0);
                      else if(!canScrollDown())
                          vpFragment.setStartPage(vpFragment.getVerticalPagerAdapter().getCount() - 1);
                      else
                      vpFragment.setStartPage(mGridPadding);
      
                      vpFragment.setPageChangeListener(new SimpleOnPageChangeListener() {
      
                          @Override
                          public void onPageSelected(int i) {
                              int newRow = mCurrentIndex.getRow() + ( -1 * (mGridPadding - i) );
      
                              if (!canScrollUp())
                                  newRow = mCurrentIndex.getRow() + i;
                              else if(!canScrollDown())
                                  newRow--;
      
                              int newCol = mCurrentIndex.getCol();
      
                              // If it's not the middle one and we need a row reset
                              if (i != mGridPadding && (0 != (mResetFlags & GRID_RESET_ROW) ))
                                  newCol = 0;
      
                              mCurrentIndex = wrapGridIndex(new GridIndex(newRow, newCol));
      
                              shouldReset = true;
      
                          }
      
                      });
      
                      return vpFragment;
                  }
                  else{
      
                      // Default my view index wrapped
                      GridIndex viewIndex = wrapGridIndex(new GridIndex((0 != (mResetFlags & GRID_RESET_COL) ) ? 0 : mCurrentIndex.getRow(), mCurrentIndex.getCol() + ( -1 * (mGridPadding - i) ) ) );
      
                      // Adjust for limited wrapping
                      if (!canScrollLeft() || !canScrollRight())
                          viewIndex.setCol(mCurrentIndex.getCol() + i);
      
                      return mGridPagerAdapter.getItem(viewIndex);
                  }
              }
      
              public int getItemPosition(Object object){
                  return POSITION_NONE;
              }
      
              @Override
              public int getCount() {
                  return (mGridPadding * 2) + 1;
              }
      
          }
      
          public interface FragmentGridPagerAdapter{
      
              public int rowCount();
              public int columnCount(int row);
              public Fragment getItem(GridIndex index);
      
          }
      
          //*****************************************************
          //*
          //*         Data Types
          //*
          //*****************************************************
      
          public class GridIndex{
      
              private int mRow = 0, mCol = 0;
      
              public GridIndex(int row, int col){
      
                  mRow = row;
                  mCol = col;
      
              }
      
              public int getRow() {
                  return mRow;
              }
      
              public void setRow(int row) {
                  this.mRow = row;
              }
      
              public int getCol() {
                  return mCol;
              }
      
              public void setCol(int col) {
                  this.mCol = col;
              }
      
              @Override
              public String toString() {
                  return "GridIndex{" +
                          "mRow=" + mRow +
                          ", mCol=" + mCol +
                          '}';
              }
      
              @Override
              public boolean equals(Object o) {
                  if (this == o) return true;
                  if (o == null || getClass() != o.getClass()) return false;
      
                  GridIndex gridIndex = (GridIndex) o;
      
                  if (mCol != gridIndex.mCol) return false;
                  if (mRow != gridIndex.mRow) return false;
      
                  return true;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-22
        • 1970-01-01
        相关资源
        最近更新 更多