it-swarm.com.ru

Совместите дочерние виды в центре Android ViewPager

Мне нужно установить дочерний вид как центр 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;
    }
}

Основная деятельность

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>

Текущий экран Current screen

ожидаемый экран expected screen

14
Noundla Sandeep

Наконец, я добавил свое решение для этого вопроса в GitHub. Я сделал несколько хороших трюков, чтобы найти решение. Вы можете получить проект по ссылке ниже (на самом деле я планировал создать блог с объяснением, но у меня не так много времени). 

Вот ссылка ( https://github.com/noundla/Sunny_Projects/tree/master/CenterLockViewPager )

Вы должны скопировать файлы из пакета com.noundla.centerviewpagersample.comps в ваш проект. И вы можете увидеть использование этого Viewpager в классе MainActivity.

Пожалуйста, дайте мне знать, если у кого-то есть проблемы с этим.

6
Noundla Sandeep

Для одного приложения я реализовал подобное следующим образом, со стандартным ViewPager:

  • Сделайте страницы полноэкранными с актуальным содержимым во внутреннем макете. Например, сделайте полноэкранный макет RelativeLayout с прозрачным фоном, а фактическое содержимое - другим RelativeLayout с центром в родительском элементе. Если я правильно помню, причина этого состояла в том, что при наличии только внутреннего макета в виде страницы ViewPager не занимал бы всю ширину экрана на некоторых устройствах, таких как Galaxy Nexus.

  • Используйте ViewPager.setPageMargin() для установки отрицательного поля страницы, т. Е. Сколько следующей/предыдущей страницы вы хотите показать. Убедитесь, что он перекрывает только прозрачную область родительского полноэкранного макета.

  • Вызовите ViewPager.setOffscreenPageLimit(), чтобы настроить количество страниц за пределами экрана, по крайней мере, на 2 от значения по умолчанию 1, чтобы обеспечить плавное перелистывание страниц, реально создавая страницы вне экрана. В противном случае вы увидите, как будут отображаться следующие/предыдущие страницы, хотя они уже частично отображаются на экране.

11
laalto

Для любого, кто расстроен тем, что ОП не обновил свой вопрос решением, приведенным здесь, есть ссылка, которая объясняет, с минимальными усилиями, как выполнить это в XML: http://blog.neteril.org/blog/2013/ 10/14/Android-tip-viewpager-with-prouruding-children/

В основном, когда вы объявляете ваш viewpager в XML, задайте ему одинаковые левый и правый отступы и установите Android: clipToPadding = "false". (ClipToPadding отсутствует в его примере xml и необходим для достижения этого эффекта)

9
Gilleland

Я нашел решение в этом посте ниже кода, который я использовал:

// 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);
    }

Это все что тебе нужно

2
Sergey Mohov

Вы можете использовать padding для viewPager и установить clipToPadding true

Джава

viewPager.setClipToPadding(false);
viewPager.setPadding(50, 0, 50, 0);

Котлин

 viewPager.clipToPadding = false
 viewPager.setPadding(50, 0, 50, 0)
0
Rasoul Miri

Мне пришлось центрировать текущую страницу в пейджере вида с разной ширины страницы , поэтому решение с отступами не подходило. Также была отключена пользовательская прокрутка (это был пейджер вида панели вкладок, прокручиваемый другим пейджером представления). Вот очень простое решение для этого - просто переопределите метод ViewPager.ScrollTo, как показано ниже (код C #, Xamarin):

public override void ScrollTo(int x, int y)
{
    x -= (int) (MeasuredWidth * (1 - Adapter.GetPageWidth(CurrentItem)) / 2);

    base.ScrollTo(x, y);
}

И если вы рассчитываете ширину страницы для каждого фрагмента, не забудьте кэшировать их в массиве.

0
Alexander Danilov