複数ページのビューをデザインしています。前のページと次のページの端を以下のように表示し、2本の指でスワイプしてページを切り替えます。
ここでViewPager
提案されているように負のページマージンを使用してみましたが、同時に両方ではなく、画面の端の1つだけが表示されます。
または、ビューの一部を画面の外に配置してアニメーション化し、ViewPager
タイプ効果を与える方法はありますか?
どうすればいいですか?よろしくお願いします!
複数ページのビューをデザインしています。前のページと次のページの端を以下のように表示し、2本の指でスワイプしてページを切り替えます。
ここでViewPager
提案されているように負のページマージンを使用してみましたが、同時に両方ではなく、画面の端の1つだけが表示されます。
または、ビューの一部を画面の外に配置してアニメーション化し、ViewPager
タイプ効果を与える方法はありますか?
どうすればいいですか?よろしくお願いします!
回答:
この件に関するブログ投稿から自分を引用する:
3番目のアプローチは、評判の高い本「Android Recipes」の共著者であるDave Smithによるものです。彼はまったく異なる方向に進み、一度に複数のページを表示するために子のクリッピングを無効にするカスタムコンテナーを使用しました。
彼が公開したサンプルコードは、実際の動作全体を示しています。彼のコンテナ(
com.example.pagercontainer.PagerContainer
)はをラップし、それ自体ViewPager
を呼び出しsetClipChildren(false);
ます。そのため、ViewPager
が1つの選択されたページにフォーカスしているViewPager
場合でも、境界内に座標がある他のページは、内に収まる限り、引き続き表示されますPagerContainer
。のサイズViewPager
をより小さいサイズにすることPagerContainer
で、ViewPager
はそのページをそのサイズにサイズ変更して、他のページが表示される余地を残すことができます。PagerContainer
ただし、ViewPager
側面に表示されるページを無視して、独自の表示境界でスワイプイベントのみを処理するため、はタッチイベントを少し手助けする必要があります。
私は同様の解決策を持っています:
ビューページャーで、左右のパディングを設定します(例:20dp)。ビューページャーのページマージンも設定してください(ページャーのパディングの半分など)。また、クリップのパディングを無効にすることを忘れないでください。
tilePager.setPadding(defaultGap, 0, defaultGap, 0);
tilePager.setClipToPadding(false);
tilePager.setPageMargin(halfGap);
アイテム全体の左右のパディングを設定します。xmlの例(page_item.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingRight="20dp"/>
<TextView
android:id="@+id/text1"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
次に、負のページ余白PageView
を2 *(前のビューのパディング)に設定します。
int margin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20*2, getResources().getDisplayMetrics());
mViewPager.setPageMargin(-margin);
オプション。空のエッジを非表示にするには、最初のアイテムの左パディングをゼロ、最後のアイテムの右パディングをゼロに設定します。これは、PageAdapter
or Page
フラグメントクラスで行うことができます。
左右のページのプレビューを表示するには、次の2つの値を設定します
viewpager.setClipToPadding(false)
viewpager.setPadding(left,0,right,0)
ビューページャーの2つのページの間にスペースが必要な場合は、viewpager.setPageMargin(int)を追加します。
誰かがまだ解決策を探している場合、負のマージンを使用せずにそれを達成するようにViewPageをカスタマイズしました。サンプルプロジェクトをここで見つけてくださいhttps://github.com/44kksharma/Android-ViewPager-Carousel-UI
ほとんどの場合に機能するはずですが、あなたはそれでもページマージンを定義できます
mPager.setPageMargin(margin in pixel);
ここからソースコードをダウンロードします(前後のページ境界を含むViewPager)
MainActivity.java
package com.deepshikha.viewpager;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseArray;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends FragmentActivity {
ViewPager pager;
MyPageAdapter obj_adapter;
String str_device;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
pager = (ViewPager) findViewById(R.id.viewpager);
differentDensityAndScreenSize(getApplicationContext());
List<Fragment> fragments = getFragments();
pager.setAdapter(obj_adapter);
pager.setClipToPadding(false);
if (str_device.equals("normal-hdpi")){
pager.setPadding(160, 0, 160, 0);
}else if (str_device.equals("normal-mdpi")){
pager.setPadding(160, 0, 160, 0);
}else if (str_device.equals("normal-xhdpi")){
pager.setPadding(160, 0, 160, 0);
}else if (str_device.equals("normal-xxhdpi")){
pager.setPadding(180, 0, 180, 0);
}else if (str_device.equals("normal-xxxhdpi")){
pager.setPadding(180, 0, 180, 0);
}else if (str_device.equals("normal-unknown")){
pager.setPadding(160, 0, 160, 0);
}else {
}
obj_adapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
pager.setPageTransformer(true, new ExpandingViewPagerTransformer());
pager.setAdapter(obj_adapter);
}
class MyPageAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
}
private List<Fragment> getFragments() {
List<Fragment> fList = new ArrayList<Fragment>();
fList.add(MyFragment.newInstance("Fragment 1",R.drawable.imags));
fList.add(MyFragment.newInstance("Fragment 2",R.drawable.image1));
fList.add(MyFragment.newInstance("Fragment 3",R.drawable.image2));
fList.add(MyFragment.newInstance("Fragment 4",R.drawable.image3));
fList.add(MyFragment.newInstance("Fragment 5",R.drawable.image4));
return fList;
}
public int differentDensityAndScreenSize(Context context) {
int value = 20;
String str = "";
if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_SMALL) {
switch (context.getResources().getDisplayMetrics().densityDpi) {
case DisplayMetrics.DENSITY_LOW:
str = "small-ldpi";
// Log.e("small 1","small-ldpi");
value = 20;
break;
case DisplayMetrics.DENSITY_MEDIUM:
str = "small-mdpi";
// Log.e("small 1","small-mdpi");
value = 20;
break;
case DisplayMetrics.DENSITY_HIGH:
str = "small-hdpi";
// Log.e("small 1","small-hdpi");
value = 20;
break;
case DisplayMetrics.DENSITY_XHIGH:
str = "small-xhdpi";
// Log.e("small 1","small-xhdpi");
value = 20;
break;
case DisplayMetrics.DENSITY_XXHIGH:
str = "small-xxhdpi";
// Log.e("small 1","small-xxhdpi");
value = 20;
break;
case DisplayMetrics.DENSITY_XXXHIGH:
str = "small-xxxhdpi";
//Log.e("small 1","small-xxxhdpi");
value = 20;
break;
case DisplayMetrics.DENSITY_TV:
str = "small-tvdpi";
// Log.e("small 1","small-tvdpi");
value = 20;
break;
default:
str = "small-unknown";
value = 20;
break;
}
} else if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
switch (context.getResources().getDisplayMetrics().densityDpi) {
case DisplayMetrics.DENSITY_LOW:
str = "normal-ldpi";
// Log.e("normal-ldpi 1","normal-ldpi");
str_device = "normal-ldpi";
value = 82;
break;
case DisplayMetrics.DENSITY_MEDIUM:
// Log.e("normal-mdpi 1","normal-mdpi");
str = "normal-mdpi";
value = 82;
str_device = "normal-mdpi";
break;
case DisplayMetrics.DENSITY_HIGH:
// Log.e("normal-hdpi 1","normal-hdpi");
str = "normal-hdpi";
str_device = "normal-hdpi";
value = 82;
break;
case DisplayMetrics.DENSITY_XHIGH:
//Log.e("normal-xhdpi 1","normal-xhdpi");
str = "normal-xhdpi";
str_device = "normal-xhdpi";
value = 90;
break;
case DisplayMetrics.DENSITY_XXHIGH:
// Log.e("normal-xxhdpi 1","normal-xxhdpi");
str = "normal-xxhdpi";
str_device = "normal-xxhdpi";
value = 96;
break;
case DisplayMetrics.DENSITY_XXXHIGH:
//Log.e("normal-xxxhdpi","normal-xxxhdpi");
str = "normal-xxxhdpi";
str_device = "normal-xxxhdpi";
value = 96;
break;
case DisplayMetrics.DENSITY_TV:
//Log.e("DENSITY_TV 1","normal-mdpi");
str = "normal-tvdpi";
str_device = "normal-tvmdpi";
value = 96;
break;
default:
// Log.e("normal-unknown","normal-unknown");
str = "normal-unknown";
str_device = "normal-unknown";
value = 82;
break;
}
} else if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) {
switch (context.getResources().getDisplayMetrics().densityDpi) {
case DisplayMetrics.DENSITY_LOW:
str = "large-ldpi";
// Log.e("large-ldpi 1","normal-ldpi");
value = 78;
break;
case DisplayMetrics.DENSITY_MEDIUM:
str = "large-mdpi";
//Log.e("large-ldpi 1","normal-mdpi");
value = 78;
break;
case DisplayMetrics.DENSITY_HIGH:
//Log.e("large-ldpi 1","normal-hdpi");
str = "large-hdpi";
value = 78;
break;
case DisplayMetrics.DENSITY_XHIGH:
// Log.e("large-ldpi 1","normal-xhdpi");
str = "large-xhdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_XXHIGH:
//Log.e("large-ldpi 1","normal-xxhdpi");
str = "large-xxhdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_XXXHIGH:
// Log.e("large-ldpi 1","normal-xxxhdpi");
str = "large-xxxhdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_TV:
//Log.e("large-ldpi 1","normal-tvdpi");
str = "large-tvdpi";
value = 125;
break;
default:
str = "large-unknown";
value = 78;
break;
}
} else if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
switch (context.getResources().getDisplayMetrics().densityDpi) {
case DisplayMetrics.DENSITY_LOW:
// Log.e("large-ldpi 1","normal-ldpi");
str = "xlarge-ldpi";
value = 125;
break;
case DisplayMetrics.DENSITY_MEDIUM:
// Log.e("large-ldpi 1","normal-mdpi");
str = "xlarge-mdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_HIGH:
//Log.e("large-ldpi 1","normal-hdpi");
str = "xlarge-hdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_XHIGH:
// Log.e("large-ldpi 1","normal-hdpi");
str = "xlarge-xhdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_XXHIGH:
// Log.e("large-ldpi 1","normal-xxhdpi");
str = "xlarge-xxhdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_XXXHIGH:
// Log.e("large-ldpi 1","normal-xxxhdpi");
str = "xlarge-xxxhdpi";
value = 125;
break;
case DisplayMetrics.DENSITY_TV:
//Log.e("large-ldpi 1","normal-tvdpi");
str = "xlarge-tvdpi";
value = 125;
break;
default:
str = "xlarge-unknown";
value = 125;
break;
}
}
return value;
}
}
いつか前、私は、このような機能を必要とし、使用しています小さなライブラリ用意しRecyclerView
てPagerSnapHelper古典の代わりに(V7サポートライブラリのバージョン25.1.0で追加を)ViewPager
:
MetalRecyclerPagerView-すべてのコードとその例を見つけることができます。
主に単一のクラスファイルで構成されています:MetalRecyclerViewPager.java(および2つのxml:attrs.xmlとids.xml))で構成されています。
それが誰かを助けることを願っています:)