我希望得到像这样的东西
我已经使用listview做了类似的事情,但我遇到的问题是,在我选择一个项目后,它将没有按下它时的颜色。 还有一个视图寻呼机,我会有一个额外的容器,我可以把我的碎片。
如果像这样的东西会起作用,那就更好了!
Android: Vertical ViewPager 我看过这个,看起来不错,但我也希望在屏幕的左侧有一些项目。
您认为最好的方法是什么? 而且,我已经有了一个导航抽屉,所以不会有新的方法。
答案 0 :(得分:1)
我已经用listview做了类似的事情,但问题是我 我选择一个项目之后就不会有它的颜色了 当它被按下时。
这是一个简单的解决方法。在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)
答案 1 :(得分:0)
尝试以下示例,
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;
}
}
}