I need an example of view pager with carousel effect.I've searched through internet but I couldn't find any example.So , have you done anything like this before ? Do you have any examples that I can examine.
You need:
activity_main
item
Custom Fragment
Custom LinearLayout
CustomPagerAdapter
Activity
I use this code:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:attrs="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.thedeveloperworldisyours.carouselviewpager.MainActivity">
<android.support.v4.view.ViewPager
android:id="#+id/activity_main_view_pager"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
item
<?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:gravity="center"
android:orientation="vertical">
<com.thedeveloperworldisyours.carouselviewpager.CustomLinearLayout
android:id="#+id/item_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/item_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/item_size_text" />
<Button
android:id="#+id/item_content"
android:layout_width="230dp"
android:layout_height="120dp"
android:background="#android:color/black"/>
</com.thedeveloperworldisyours.carouselviewpager.CustomLinearLayout>
</LinearLayout>
Custom Fragment
public class CustomFragment extends Fragment {
public static Fragment newInstance(Activity context, int position, float scale) {
Bundle bundle = new Bundle();
bundle.putInt("position", position);
bundle.putFloat("scale", scale);
return Fragment.instantiate(context, CustomFragment.class.getName(), bundle);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
return null;
}
LinearLayout linearLayout = (LinearLayout)
inflater.inflate(R.layout.item, container, false);
int position = this.getArguments().getInt("position");
TextView textView = (TextView) linearLayout.findViewById(R.id.item_text);
textView.setText(String.valueOf(position));
CustomLinearLayout root = (CustomLinearLayout) linearLayout.findViewById(R.id.item_root);
float scale = this.getArguments().getFloat("scale");
root.setScaleBoth(scale);
return linearLayout;
}
}
Custom LinearLayout
public class CustomLinearLayout extends LinearLayout {
private float mScale = BIG_SCALE;
public CustomLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomLinearLayout(Context context) {
super(context);
}
public void setScaleBoth(float scale) {
this.mScale = scale;
this.invalidate(); // If you want to see the mScale every time you set
// mScale you need to have this line here,
// invalidate() function will call onDraw(Canvas)
// to redraw the view for you
}
#Override
protected void onDraw(Canvas canvas) {
// The main mechanism to display mScale animation, you can customize it
// as your needs
int w = this.getWidth();
int h = this.getHeight();
canvas.scale(mScale, mScale, w / 2, h / 2);
super.onDraw(canvas);
}
}
The most import thing is the adapter
public class CustomPagerAdapter extends FragmentPagerAdapter implements ViewPager.PageTransformer {
public final static float BIG_SCALE = 1.0f;
public final static float SMALL_SCALE = 0.7f;
public final static float DIFF_SCALE = BIG_SCALE - SMALL_SCALE;
private Activity mContext;
private FragmentManager mFragmentManager;
private float mScale;
public CustomPagerAdapter(Activity context, FragmentManager fragmentManager) {
super(fragmentManager);
this.mFragmentManager = fragmentManager;
this.mContext = context;
}
#Override
public Fragment getItem(int position) {
// make the first mViewPager bigger than others
if (position == FIRST_PAGE)
mScale = BIG_SCALE;
else
mScale = SMALL_SCALE;
return CustomFragment.newInstance(mContext, position, mScale);
}
#Override
public int getCount() {
return PAGES;
}
#Override
public void transformPage(View page, float position) {
CustomLinearLayout myLinearLayout = (CustomLinearLayout) page.findViewById(R.id.item_root);
float scale = BIG_SCALE;
if (position > 0) {
scale = scale - position * DIFF_SCALE;
} else {
scale = scale + position * DIFF_SCALE;
}
if (scale < 0) scale = 0;
myLinearLayout.setScaleBoth(scale);
}
}
and now the Activity
public class MainActivity extends AppCompatActivity {
public final static int PAGES = 5;
public final static int FIRST_PAGE = 0 ;
public CustomPagerAdapter mAdapter;
public ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.activity_main_view_pager);
mAdapter = new CustomPagerAdapter(this, this.getSupportFragmentManager());
mViewPager.setAdapter(mAdapter);
mViewPager.setPageTransformer(false, mAdapter);
// Set current item to the middle page so we can fling to both
// directions left and right
mViewPager.setCurrentItem(FIRST_PAGE);
// Necessary or the mViewPager will only have one extra page to show
// make this at least however many pages you can see
mViewPager.setOffscreenPageLimit(3);
// Set margin for pages as a negative number, so a part of next and
// previous pages will be showed
mViewPager.setPageMargin(-400);
}
}
Also you check this Tutorial and this exmple in GitHub.
Please find the link below as solution to implement Carousel in android using View Pager:
https://github.com/haerulmuttaqin/SwipeViewPager
Hope it helps anyone looking for answers.
You can have a look at CarouselView.
Might help you if you need a simple carouselview.
Add view in your layout:
<com.synnapps.carouselview.CarouselView
android:id="#+id/carouselView"
android:layout_width="match_parent"
android:layout_height="200dp"
app:fillColor="#FFFFFFFF"
app:pageColor="#00000000"
app:radius="6dp"
app:slideInterval="3000"
app:strokeColor="#FF777777"
app:strokeWidth="1dp"/>
Add images by implementing callback:
public class SampleCarouselViewActivity extends AppCompatActivity {
CarouselView carouselView;
int[] sampleImages = {R.drawable.image_1, R.drawable.image_2, R.drawable.image_3, R.drawable.image_4, R.drawable.image_5};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample_carousel_view);
carouselView = (CarouselView) findViewById(R.id.carouselView);
carouselView.setPageCount(sampleImages.length);
carouselView.setImageListener(imageListener);
}
ImageListener imageListener = new ImageListener() {
#Override
public void setImageForPosition(int position, ImageView imageView) {
imageView.setImageResource(sampleImages[position]);
}
};
}
Related
I have screen where upper half is covered with the cameraView and bottom half is a slidingPanel which contains a fragment and the fragment contains a recyclerView. I want the screen to be portrait only but when the orientation changes to landscape the object should rotate to 90 degrees at its position. I am rotating the FrameLayout which is containing the Fragment and which contains the RecyclerView. The object rotates perfectly but the problem is recyclerView is behaving very strange. When the frameLayout rotated to 90 degrees RecyclerView instead of scrolling vertically in landscape mode it is scrolling when scroll horizontally.
Below is my XML containing the FrameLayout which is been rotated to 90 degree.
<com.sothree.slidinguppanel.SlidingUpPanelLayout
xmlns:sothree="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/tools"
android:id="#+id/sliding_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
sothree:umanoDragView="#+id/layout_dragger"
sothree:umanoPanelHeight="68dp"
sothree:umanoShadowHeight="4dp"
app:ignore="NamespaceTypo"
android:background="#color/transparent">
<com.otaliastudios.cameraview.CameraView
android:id="#+id/camera"
android:keepScreenOn="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
sothree:cameraFacing="front"
sothree:cameraSessionType="video"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/layout_dragger"
android:layout_width="match_parent"
android:layout_height="68dp">
<ImageView
android:id="#+id/up_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/up_arrow"
android:layout_alignParentLeft="true"/>
<ImageView
android:id="#+id/record"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/record"
android:layout_centerInParent="true"/>
</RelativeLayout>
<FrameLayout
android:id="#+id/frame_video"
android:layout_width="match_parent"
android:layout_height="250dp">
</FrameLayout>
</LinearLayout>
</LinearLayout>
</com.sothree.slidinguppanel.SlidingUpPanelLayout>
Below is my Class which contains the rotating animation.
public class MirrorFragment extends Fragment {
private LinearLayout mQueen;
private Button mHidden, accept, decline;
private static final String TAG = "DemoActivity";
private DraggingPanel mDraggingPanel;
private LinearLayout mMainLayout;
private FrameLayout frameContainer;
Fragment childFragment;
private Context mContext;
int height,width;
int draggingPanelHeight, draggingPanelWidth;
private ImageView iv_record, up_arrow;
RelativeLayout.LayoutParams param;
FrameLayout.LayoutParams frameParam;
SlidingUpPanelLayout mLayout;
private Animation toLandAnim, toPortAnim;
private OrientationListener orientationListener;
private CameraView cameraView;
private boolean mCapturingVideo =false;
Fragment fragment;
private static final String VIDEO_EXTENSION = ".mp4";
private String mNextVideoAbsolutePath;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_mirror, null);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mContext = getContext();
fragment = (MirrorFragment)getFragmentManager().findFragmentByTag("mirror_frag");
initViews(view);
// setWidthOfBottomContainer();
up_arrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
iv_record.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mCapturingVideo){
stopVideo();
}else{
captureVideo();
}
}
});
}
private void initViews(View view) {
mLayout = (SlidingUpPanelLayout) view.findViewById(R.id.sliding_layout);
mLayout.setAnchorPoint(0.5f);
mMainLayout = view.findViewById(R.id.main_layout);
frameContainer = view.findViewById(R.id.frame_video);
cameraView = view.findViewById(R.id.camera);
up_arrow = view.findViewById(R.id.up_arrow);
iv_record = view.findViewById(R.id.record);
cameraView.setLifecycleOwner(fragment.getViewLifecycleOwner());
cameraView.mapGesture(Gesture.PINCH, GestureAction.ZOOM); // Pinch to zoom!
toLandAnim= AnimationUtils.loadAnimation(mContext, R.anim.view_to_landscape);
toPortAnim= AnimationUtils.loadAnimation(mContext, R.anim.view_to_portrait);
orientationListener = new MirrorFragment.OrientationListener(mContext);
childFragment = new DiscoveryFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.frame_video, childFragment);
transaction.addToBackStack(null);
transaction.commit();
}
#Override
public void onResume() {
super.onResume();
cameraView.start();
}
#Override
public void onPause() {
super.onPause();
cameraView.stop();
}
#Override
public void onDestroy() {
super.onDestroy();
cameraView.destroy();
}
#Override
public void onStart() {
orientationListener.enable();
super.onStart();
}
#Override
public void onStop() {
super.onStop();
orientationListener.disable();
}
#Override
public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
super.onMultiWindowModeChanged(isInMultiWindowMode);
}
private void getHeightWidth() {
/* draggingPanelHeight = mLayout.getHeight();
draggingPanelWidth = mLayout.getWidth();*/
DisplayMetrics displayMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
height = displayMetrics.heightPixels;
width = displayMetrics.widthPixels;
}
private class OrientationListener extends OrientationEventListener{
final int ROTATION_0 = 1;
final int ROTATION_90 = 2;
final int ROTATION_180 = 3;
final int ROTATION_270 = 4;
private int rotation = 0;
public OrientationListener(Context context) { super(context); }
#Override public void onOrientationChanged(int orientation) {
if( (orientation < 35 || orientation > 325) && rotation!= ROTATION_0){ // PORTRAIT
getHeightWidth();
rotation = ROTATION_0;
frameContainer.startAnimation(toPortAnim);
}
else if( orientation > 145 && orientation < 215 && rotation!=ROTATION_180){ // REVERSE PORTRAIT
getHeightWidth();
rotation = ROTATION_180;
frameContainer.startAnimation(toPortAnim);
}
else if(orientation > 55 && orientation < 125 && rotation!=ROTATION_270){ // REVERSE LANDSCAPE
getHeightWidth();
rotation = ROTATION_270;
//param = new RelativeLayout.LayoutParams((int)width/2,ViewGroup.LayoutParams.MATCH_PARENT);
frameContainer.setLayoutParams(new LinearLayout.LayoutParams((int)height/2,(int)width));
frameContainer.startAnimation(toLandAnim);
}
else if(orientation > 235 && orientation < 305 && rotation!=ROTATION_90){ //LANDSCAPE
getHeightWidth();
rotation = ROTATION_90;
//param = new RelativeLayout.LayoutParams((int)width/2,ViewGroup.LayoutParams.MATCH_PARENT);
frameContainer.setLayoutParams(new LinearLayout.LayoutParams((int)height/2,(int)width));
frameContainer.startAnimation(toLandAnim);
}
}
}
}
My problem is how to change the scrolling behaviour of recyclerView when it rotates to 90 degrees. Please find attached screenshot for reference.
If you see the attached screenshot then you can see when I rotated the frame container it rotated object inside it which is recylerView but in landscape it's scrolling like it scroll in portrait mode.
I have made an app in which I have added functionality of vertical swipe using ViewPager class. Now I need help to also add Horizontal swipe. I have seen several projects on GitHub for vertical & horizontal swipe together in same activity but could not figure out how can I integrate this with my code.
Here is how I implemented Vertical Swipe:
activity_main
<VerticalViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
MainActivity
public class MainActivity extends AppCompatActivity SlidingFragment.AppData {
List<Data> mData = new ArrayList<>();
ScreenSlidePagerAdapter screenSlidePagerAdapter;
VerticalViewPager verticalViewPager;
DatabaseHelper dbHelper = new DatabaseHelper(this);
public static int DATA_CARDS = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mains);
mData = dbHelper.getAll(Data.class);
DATA_CARDS = mData.size();
ScreenSlidePagerAdapter screenSlidePagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
VerticalViewPager verticalViewPager = (VerticalViewPager) findViewById(R.id.pager);
verticalViewPager.setAdapter(screenSlidePagerAdapter);
}
#Override
public JSONObject getData(int position) {
String body = "";
String imageUrl = "";
JSONObject jsonObject = new JSONObject();
try {
body = mData.get(position).getContent();
imageUrl = mData.get(position).getImage();
jsonObject.put("image_url", imageUrl);
jsonObject.put("body", body);
} catch (Exception e){
e.printStackTrace();
}
return jsonObject;
}
}
ScreenSlidePagerAdapter
public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
private static final int NUM_PAGES = MainActivity.DATA_CARDS;
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
SlidingFragment slidingFragment = new SlidingFragment();
Bundle bundle = new Bundle();
bundle.putInt("position", position);
slidingFragment.setArguments(bundle);
return slidingFragment;
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
VerticalViewPager
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setPageTransformer(true, new VerticalPageTransformer());]
setOverScrollMode(OVER_SCROLL_NEVER);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
fragment_sliding
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fresco="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="MainActivity">
<com.facebook.drawee.view.SimpleDraweeView
android:id="#+id/image"
fresco:roundedCornerRadius="5dp"
android:layout_width="match_parent"
android:layout_margin="#dimen/fragment_image_margin"
android:layout_height="200dp"
fresco:placeholderImage="#drawable/logo" />
<TextView
android:id="#+id/text"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_below="#+id/image"/>
</RelativeLayout>
SlidingFragment
public class SlidingFragment extends Fragment {
private AppData mAppData;
private int mPosition;
public interface AppData {
JSONObject getData(int position);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
mAppData = (AppData) context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_sliding, container, false);
return rootView;
}
#Override
public void onResume() {
super.onResume();
populateData();
}
private void populateData(){
String body;
String imageUrl;
JSONObject jsonObject = mAppData.getData(getArguments().getInt("position"));
try {
body = jsonObject.getString("body");
imageUrl = jsonObject.getString("image_url");
((TextView) getView().findViewById(R.id.text)).setText(body);
Uri uri = Uri.parse(imageUrl);
SimpleDraweeView draweeView = (SimpleDraweeView) getView().findViewById(R.id.image);
draweeView.setImageURI(uri);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Any help will be appreciated.
I've tried to implement swiperefreshlayout in my code but it keeps refreshing the entire pager instead of just refreshing when i'm on the first Fragment i.e the 0th Fragment.
I tried setting refresh to false as shown, but the loader still appears, and doesn't reset when I go back to the 0th Fragment again.
On setting swiperefreshlayout.enable(false), I can't refresh it anywhere.
Can anyone suggest an alternative?
This is my XML file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parentLinearLayout"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<lbbdapp.littleblackbook.com.littleblackbook.Support.VerticalViewPager
android:id="#+id/verticalViewPager"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
And this is my activity:
public class FeedActivity extends ActionBarActivity {
PageAdapter mPageAdapter;
ProgressBar mProgressBar;
ProgressDialog prog;
ViewPager pager;
String article_id;
private float x1, x2;
SwipeRefreshLayout mSwipeRefreshLayout;
ArrayList<FragmentObject> mObjectsDataList;
ArrayList<ArticleObject> mArticleDataList=new ArrayList<ArticleObject>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.feed_layout);
mObjectsDataList = new ArrayList<FragmentObject>();
DataFetcherTask myTask = new DataFetcherTask();
myTask.execute();
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
mSwipeRefreshLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_blue_dark,
android.R.color.holo_purple,
android.R.color.darker_gray);
pager=(ViewPager)findViewById(R.id.verticalViewPager);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
if(pager.getCurrentItem()==0) {
Log.wtf("current item is 0", "0");
mSwipeRefreshLayout.setRefreshing(true);
Log.wtf("Swiping", "Refreshing");
(new Handler()).postDelayed(new Runnable() {
#Override
public void run() {
mSwipeRefreshLayout.setRefreshing(false);
DataFetcherTask myTask = new DataFetcherTask();
myTask.execute();
}
}, 3000);
}
else{
mSwipeRefreshLayout.setRefreshing(false);
}
}
});
}
This is my vertical ViewPager:
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
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);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
Instead of extending SwipeRefesh over ViewGroup use it inside the each Fragment of ViewPager.
Once this is resolved now you need to check scroll down gesture of ViewPager and SwipeRefresh.
public class NEWSwipeRefresh extends SwipeRefreshLayout {
private View mTargetView;
public NEWSwipeRefresh(Context context) {
this(context, null);
}
public NEWSwipeRefresh(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setTarget(View view) {
mTargetView = view;
}
#Override
public boolean canChildScrollUp() {
if (mTargetView instanceof YOURVIEW) {
final StaggeredGridView absListView = (YOURVIEW)mTargetView;
return absListView.getChildCount() > 0
&& (absListView.getFirstVisiblePosition() > 0 || absListView
.getChildAt(0).getTop() < absListView
.getPaddingTop());
} else {
return super.canChildScrollUp();
}
}
}
Normally swipe refresh returns -1 and it gives swipe gesture to it's parent now I have overridden it here for listview/gridview so that it can check for visible items, if it is on top then it will give swipe to parent or otherwise it will give it to children.
Well, I was trying to figure this out since few days and it's quite simple. Just put the SwipeRefreshLayout as the parent element of ViewPager and just disable the SwipeRefreshLayout on the particular fragment using OnPageChangeListener as follows:
// viewpager change listener
OnPageChangeListener viewPagerPageChangeListener = new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
//for the 0th pos disable SwipeRefreshLayout;
if(position != 0){
swipeRefreshLayout.setEnabled(false);
}else swipeRefreshLayout.setEnabled(true);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}};
I've written a small activity that uses fragments with a ViewPager to show images.
I've also implemented a custom GestureListener to catch the swipe up and swipe down gestures without interferring with the ViewPager's own gesture handling. What I want to achieve is to show a layout when the user swipes down.
Problem is, I haven't found out how to execute the animation when the gesture listener detects the swipe down gesture.
EDIT: Added context and view to MyGestureListener to reference the view and context. Logging shows that the gesture is detected correctly and the view inside MyGestureListener is the correct one but nothing gets animated.
Code as follows.
Activity:
public class MainActivity extends FragmentActivity {
private GestureDetector gestureDetector;
private ViewPager vwpMain;
private PagerAdapter pgaMain;
private RelativeLayout layout;
private LinearLayout topLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layout = (RelativeLayout) findViewById(R.id.container);
topLayout = (LinearLayout) findViewById(R.id.topPanel);
vwpMain = (ViewPager) findViewById(R.id.vwpMain);
pgaMain = new MyPagerAdapter(getSupportFragmentManager());
vwpMain.setAdapter(pgaMain);
gestureDetector = new GestureDetector(this, new MyGestureListener(getApplicationContext(), topLayout));
layout.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
gestureDetector.onTouchEvent(event);
return true;
}
});
}
public boolean dispatchTouchEvent(MotionEvent ev) {
super.dispatchTouchEvent(ev);
return gestureDetector.onTouchEvent(ev);
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public Fragment getItem(int pos) {
return ImageFragment.create(pos);
}
#SuppressLint("SdCardPath")
#Override
public int getCount() {
File f = new File("/mnt/sdcard/FragmentImages/");
return f.listFiles().length;
}
}
Fragment:
public class ImageFragment extends Fragment {
private int pageNumber;
private ImageView i;
public static ImageFragment create(int pageNumber) {
ImageFragment f = new ImageFragment();
Bundle b = new Bundle();
b.putInt("index", pageNumber);
int indice = pageNumber + 1;
String ruta = Environment.getExternalStorageDirectory().getPath()
+ "/FragmentImages/imagen_" + indice + ".jpg";
b.putString("file", ruta);
f.setArguments(b);
return f;
}
public ImageFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pageNumber = getArguments().getInt("index");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout containing a title and body text.
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.fragment_image, container, false);
i = (ImageView) rootView.findViewById(R.id.imgImagen);
BitmapWorkerTask task = new BitmapWorkerTask(i);
task.execute(getArguments().getString("file"));
return rootView;
}
public int getPageNumber() {
return pageNumber;
}
public class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private String data;
public BitmapWorkerTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
#Override
protected Bitmap doInBackground(String... params) {
data = params[0];
return BitmapFactory.decodeFile(data);
}
#Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
}
Gesture listener:
public class MyGestureListener extends SimpleOnGestureListener {
private static final int SWIPE_MIN_DISTANCE = 75;
private static final int SWIPE_MAX_OFF_PATH = 100;
private static final int SWIPE_THRESHOLD_VELOCITY = 50;
public Context context;
public View view;
public MyGestureListener() {
super();
context = _context;
view = _view;
}
#Override
public boolean onDown(MotionEvent event) {
return true;
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
float dX = e2.getX() - e1.getX();
float dY = e1.getY() - e2.getY();
if (Math.abs(dY) < SWIPE_MAX_OFF_PATH
&& Math.abs(velocityX) >= SWIPE_THRESHOLD_VELOCITY
&& Math.abs(dX) >= SWIPE_MIN_DISTANCE) {
if (dX > 0) {
Log.d("Fragment", "Swiping right");
} else {
Log.d("Fragment", "Swiping left");
}
} else if (Math.abs(dX) < SWIPE_MAX_OFF_PATH
&& Math.abs(velocityY) >= SWIPE_THRESHOLD_VELOCITY
&& Math.abs(dY) >= SWIPE_MIN_DISTANCE) {
if (dY > 0) {
Log.d("Fragment", "Swiping up");
} else {
Log.d("Fragment", "Swiping down");
Animation a = AnimationUtils.loadAnimation(context, R.anim.show_top);
Log.d("Fragment", view.toString());
view.startAnimation(a);
}
}
return false;
}
}
Layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<LinearLayout
android:id="#+id/topPanel"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="horizontal"
android:visibility="gone" >
<TextView
android:id="#+id/topPanelTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/topPanelText"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#android:color/black" />
</LinearLayout>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/vwpMain"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Animation:
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fromYDelta="-100%"
android:toYDelta="0%" >
</translate>
Found a solution. I changed the swiping down detection code to this:
Log.d("Fragment", "Swiping down");
Animation showTopPanel = AnimationUtils.loadAnimation(context, R.anim.show_top);
topView.bringToFront();
topView.setVisibility(View.VISIBLE);
topView.startAnimation(showTopPanel);
Then the animation showed correctly.
I am trying to show horizontal scroll view with images to scroll in two directions.Previously for this i used Gallery View but galleryview is deprected ,i am using horizontal scroll view instead of gallery view but horizontal scroll view is different with gallery view.
Now i have to do two implementation
1) Scrolling in two directions continuously.
2) Center lock feature as same as gallery.
My screen looks like
you can use viewpager,
try this code and modify it as your need .
note : this not my code already found it on the net belong to:
( Dave Smith,#devunwired Date: 8/17/12 PagerActivity).
MainActivity:
public class MainActivity extends Activity{
PagerContainer mContainer;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContainer = (PagerContainer) findViewById(R.id.pager_container);
ViewPager pager = mContainer.getViewPager();
PagerAdapter adapter = new MyPagerAdapter();
pager.setAdapter(adapter);
// Necessary or the pager will only have one extra page to show
// make this at least however many pages you can see
pager.setOffscreenPageLimit(adapter.getCount());
// A little space between pages
pager.setPageMargin(15);}
// Nothing special about this adapter, just throwing up colored views for
// demo
private class MyPagerAdapter extends PagerAdapter{
#Override
public Object instantiateItem(ViewGroup container, int position){
TextView view = new TextView(MainActivity.this);
view.setText("Item " + position);
view.setGravity(Gravity.CENTER);
view.setBackgroundColor(Color.argb(255, position * 50,
position * 10, position * 50));
container.addView(view);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object)
{
container.removeView((View) object);}
#Override
public int getCount(){
return 5;
}
#Override
public boolean isViewFromObject(View view, Object object)
{
return (view == object);
}}}
PagerContainer:
public class PagerContainer extends FrameLayout implements
ViewPager.OnPageChangeListener {
private ViewPager mPager;
boolean mNeedsRedraw = false;
public PagerContainer(Context context) {
super(context);
init();
}
public PagerContainer(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public PagerContainer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
setClipChildren(false);
}
#Override
protected void onFinishInflate() {
try {
mPager = (ViewPager) getChildAt(0);
mPager.setOnPageChangeListener(this);
} catch (Exception e) {
throw new IllegalStateException("The root child of PagerContainer must be a
ViewPager");
}
}
public ViewPager getViewPager() {
return mPager;
}
private Point mCenter = new Point();
private Point mInitialTouch = new Point();
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCenter.x = w / 2;
mCenter.y = h / 2;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
//We capture any touches not already handled by the ViewPager
// to implement scrolling from a touch outside the pager bounds.
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mInitialTouch.x = (int)ev.getX();
mInitialTouch.y = (int)ev.getY();
default:
ev.offsetLocation(mCenter.x - mInitialTouch.x, mCenter.y -
mInitialTouch.y);
break;
}
return mPager.dispatchTouchEvent(ev);
}
public void onPageScrolled(int position, float positionOffset, int
positionOffsetPixels) {
//Force the container to redraw on scrolling.
//Without this the outer pages render initially and then stay static
if (mNeedsRedraw) invalidate();
}
public void onPageSelected(int position) { }
public void onPageScrollStateChanged(int state) {
mNeedsRedraw = (state != ViewPager.SCROLL_STATE_IDLE);
}
}
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.testviewpager.PagerContainer
android:id="#+id/pager_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#CCC" >
<android.support.v4.view.ViewPager
android:layout_width="150dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal" />
</com.example.testviewpager.PagerContainer>
</RelativeLayout>
hope help you.