Je dois définir la vue enfant comme centre de ViewPager et j'aimerais également montrer une partie des vues précédente et suivante aux côtés de la vue actuelle (comme l’écran actuel situé en dessous de 1). Mais actuellement, la vue actuelle commence à gauche du ViewPager (comme l’écran attendu en dessous de 2). Comment puis-je y arriver?
Voici mon code ..
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;
}
}
Activité principale
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>
Écran actuel
écran attendu
Enfin, j'ai ajouté ma solution à cette question dans GitHub. J'ai fait quelques jolies astuces pour trouver la solution de contournement. Vous pouvez obtenir le projet à l’aide du lien ci-dessous (j’ai en fait prévu de créer un blog avec l’explication, mais je n’ai pas beaucoup de temps pour le faire).
Voici le link ( https://github.com/noundla/Sunny_Projects/tree/master/CenterLockViewPager )
Vous devez copier les fichiers du package com.noundla.centerviewpagersample.comps
dans votre projet. Et vous pouvez voir l'utilisation de ce Viewpager dans la classe MainActivity
.
S'il vous plaît laissez-moi savoir si quelqu'un a des problèmes avec cela.
Pour une application, j'ai implémenté la même manière de la manière suivante, avec la variable ViewPager
standard:
Rendre les pages en plein écran avec le contenu réel dans une disposition interne. Par exemple, définissez la disposition en plein écran sur RelativeLayout
avec un arrière-plan transparent et le contenu réel sur RelativeLayout
centré dans le parent. Si je me souviens bien, la raison en est qu’avec la disposition interne uniquement en tant que page, la ViewPager
n’aurait pas pris toute la largeur de l’écran sur certains appareils tels que Galaxy Nexus.
Utilisez ViewPager.setPageMargin()
pour définir une marge de page négative, c’est-à-dire le pourcentage de la page suivante/précédente que vous souhaitez afficher. Assurez-vous qu'il ne recouvre que la région transparente de la présentation plein écran parente.
Appelez ViewPager.setOffscreenPageLimit()
pour régler le nombre de pages hors écran sur au moins 2
à partir du 1
par défaut afin de garantir une pagination fluide en créant réellement les pages hors écran. Sinon, vous verrez les pages suivantes/précédentes en cours de dessin alors qu’elles ne sont déjà que partiellement affichées à l’écran.
Pour ceux qui sont bouleversés par le fait que le PO n'ait pas mis à jour sa question avec la solution, voici un lien qui explique, avec un minimum d'effort, comment résoudre cela en XML: http://blog.neteril.org/blog/2013/ 10/14/Android-tip-viewpager-with-protruding-children/
En gros, lorsque vous déclarez votre viewpager en XML, attribuez-lui le même remplissage gauche et droit et définissez Android: clipToPadding = "false". (Le clipToPadding manque dans son exemple xml et est nécessaire pour obtenir cet effet)
J'ai trouvé la solution dans ce post , en dessous du code que j'ai utilisé:
// 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);
code dpToPx:
public static int dpToPx(int dp, Context context) {
float density = context.getResources().getDisplayMetrics().density;
return Math.round((float) dp * density);
}
C'est tout ce dont vous avez besoin
Vous pouvez utiliser padding pour viewPager et set clipToPadding true
Java
viewPager.setClipToPadding(false);
viewPager.setPadding(50, 0, 50, 0);
Kotlin
viewPager.clipToPadding = false
viewPager.setPadding(50, 0, 50, 0)
Je devais centrer la page en cours dans le pageur de vue avec différentes largeurs de page , la solution avec des rembourrages n’était donc pas appropriée. Le défilement de l'utilisateur était également désactivé (il s'agissait d'un pager de vue de barre de tabulation, défilé par un autre pager de vue). Voici une solution très simple pour cela: substituez simplement la méthode ViewPager.ScrollTo comme ceci (code C #, Xamarin):
public override void ScrollTo(int x, int y)
{
x -= (int) (MeasuredWidth * (1 - Adapter.GetPageWidth(CurrentItem)) / 2);
base.ScrollTo(x, y);
}
Et si vous calculez la largeur de page pour chaque fragment, n'oubliez pas de les mettre en cache dans un tableau.