我需要将子视图设置为ViewPager的中心,并且我还要向当前视图边显示下一个和上一个视图的某些部分(如1下的当前屏幕)。但目前当前视图从ViewPager的左侧开始(如预期的屏幕低于2)。我怎样才能做到这一点?
这是我的代码..
MyViewPagerAdapter
public class MyViewPagerAdapter extends PagerAdapter {
private Activity mActivity;
private int mPageCount;
public MyViewPagerAdapter(Activity activity,int pageCount) {
mActivity = activity;
mPageCount = pageCount;
}
@Override
public int getCount() {
return mPageCount;
}
@Override
public boolean isViewFromObject(View view, Object obj) {
return (view ==(View)obj);
}
@Override
public Object instantiateItem(ViewGroup container,final int position) {
ViewGroup viewGroup = (ViewGroup)mActivity.getLayoutInflater().inflate(
R.layout.item_view, null);
viewGroup.setBackgroundColor(randomColor());
TextView textView = (TextView)viewGroup.findViewById(R.id.textView1);
textView.setText("Page: "+(position+1));
Button button = (Button) viewGroup.findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mActivity, "Hey, Its clicked!!! at page "+(position+1), Toast.LENGTH_LONG).show();
}
});
container.addView(viewGroup);
return viewGroup;
}
Random rnd = new Random();
private int randomColor(){
return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
}
@Override
public void destroyItem(ViewGroup collection, int position, Object view) {
//must be overridden else throws exception as not overridden.
Log.d("Tag", collection.getChildCount()+"");
collection.removeView((View) view);
}
@Override
public float getPageWidth(int position) {
return 0.8f;
}
}
MainActivity
public class MainActivity extends Activity {
private ViewPager viewPager;
LinearLayout linearLayout;
private int ID = 100;
private final int count = 8;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewPager);
linearLayout = (LinearLayout) findViewById(R.id.indicator_layout);
generateIndicators(count);
MyViewPagerAdapter adapter = new MyViewPagerAdapter(this, count);
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
int oldPosition = 0;
@Override
public void onPageSelected(int position) {
//this changes the old position's view state image
((TextView)linearLayout.getChildAt(oldPosition)).setText("");
oldPosition = position;
//this changes the current position's view state image
((TextView)linearLayout.getChildAt(position)).setText((position+1)+"");
}
//this method will be called repeatedly upto another item comes as front one(active one)
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
//this will be called as per scroll state
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
viewPager.setOffscreenPageLimit(4);
}
private void generateIndicators(int count) {
/// Converts 14 dip into its equivalent px
int padd = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getResources().getDisplayMetrics());
for(int i=0;i<count;i++){
TextView textView = new TextView(this);
textView.setId(ID+i);
final int currentItem = i;
textView.setBackgroundResource(R.drawable.white_cell);
textView.setPadding(padd,padd,padd,padd);
/// Converts 14 dip into its equivalent px
int size = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());
textView.setTextSize(size);
textView.setGravity(Gravity.CENTER);
/// Converts 14 dip into its equivalent px
int px = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(px, px);
linearLayout.addView(textView,params);
}
((TextView)linearLayout.getChildAt(0)).setText("1");
}
}
activity_main.xml中
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</android.support.v4.view.ViewPager>
<LinearLayout
android:id="@+id/indicator_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="19dp" >
</LinearLayout>
</RelativeLayout>
item_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="match_parent"
android:id="@+id/root_view"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="click me" />
</LinearLayout>
当前屏幕
预期的屏幕
答案 0 :(得分:11)
对于一个应用程序,我使用标准ViewPager
:
使用内部布局中的实际内容全屏显示页面。例如,将全屏布局设为RelativeLayout
,背景为透明,实际内容为另一个RelativeLayout
,位于父级中心。如果我没记错的话,其原因在于,只有内部布局作为页面,ViewPager
就不会占用某些设备上的所有屏幕宽度,例如Galaxy Nexus。
使用ViewPager.setPageMargin()
设置负页边距,即您要显示的下一页/上一页的页数。确保它只与父全屏布局的透明区域重叠。
调用ViewPager.setOffscreenPageLimit()
将屏幕外页数从默认2
调整为至少1
,以确保通过在屏幕外创建页面来实现平滑分页。否则,您将在屏幕上部分显示的同时看到下一页/上一页正在绘制。
答案 1 :(得分:9)
对于任何不满意的人来说,OP没有用解决方案更新他的问题,这是一个链接,用最简单的努力解释如何在XML中解决这个问题:http://blog.neteril.org/blog/2013/10/14/android-tip-viewpager-with-protruding-children/
基本上,当你用XML声明你的viewpager时,给它相同的左右填充并设置android:clipToPadding =“false”。 (他的xml示例中缺少clipToPadding,这是实现此效果所必需的)
答案 2 :(得分:6)
最后,我在GitHub中添加了我的解决方案。我已经做了一些很好的技巧来获得解决方案。您可以从以下链接获取项目(实际上我已经计划创建一个带有解释的博客,但我有很多时间可以做)。
以下是link(https://github.com/noundla/Sunny_Projects/tree/master/CenterLockViewPager)
您必须将com.noundla.centerviewpagersample.comps
包中的文件复制到您的项目中。您可以在MainActivity
类中查看该Viewpager的用法。
如果有人有问题,请告诉我。
答案 3 :(得分:2)
我在post找到了解决方案,低于我使用的代码:
// Offset between sibling pages in dp
int pageOffset = 20;
// Visible part of sibling pages at the edges in dp
int sidePageVisibleWidth = 10;
// Horizontal padding will be
int horPadding = pageOffset + sidePageVisibleWidth;
// Apply parameters
viewPager.setClipToPadding(false);
viewPager.setPageMargin(UIUtil.dpToPx(pageOffset, getContext()));
viewPager.setPadding(UIUtil.dpToPx(horPadding, getContext()), 0, UIUtil.dpToPx(horPadding, getContext()), 0);
dpToPx代码:
public static int dpToPx(int dp, Context context) {
float density = context.getResources().getDisplayMetrics().density;
return Math.round((float) dp * density);
}
这就是你所需要的一切
答案 4 :(得分:1)
您可以对viewPager使用填充,并将 clipToPadding 设置为false
Java
viewPager.setClipToPadding(false);
viewPager.setPadding(50, 0, 50, 0);
科特林
viewPager.clipToPadding = false
viewPager.setPadding(50, 0, 50, 0)
答案 5 :(得分:0)
我必须在不同页面宽度的视图寻呼机中居中当前页面,因此使用填充的解决方案不合适。用户滚动也被禁用(它是标签栏视图寻呼机,由另一个视图寻呼机滚动)。这是一个非常简单的解决方案 - 只需覆盖ViewPager.ScrollTo方法(C#代码,Xamarin):
public override void ScrollTo(int x, int y)
{
x -= (int) (MeasuredWidth * (1 - Adapter.GetPageWidth(CurrentItem)) / 2);
base.ScrollTo(x, y);
}
如果您计算每个片段的页面宽度,请不要忘记将它们缓存在数组中。
答案 6 :(得分:-2)
将 HorizontalScrollView 类扩展为滚动视图的父级。在 onMeasure()方法中,您可以指定每个子项的宽度和高度。有点麻烦,但效果会很好,你可以很好地抓住孩子的观点。