Android: Paging on custom class created from HorizontalScrollView is not smooth - android

I am trying to create an infinite pager from a HorizontalScrollView.
It does infinitely scroll by continuously rearranging the children views as needed, but once it has to start moving the views (adding to the left or the right) it is no longer scrolling smoothly. I am trying to figure out how to get it to scroll to the next page smoothly even after it changes the child position.
Here is the class as I have it so far:
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
public class PagerInfinite extends HorizontalScrollView {
private LinearLayout contents;
private Map<Integer, Integer> childWidths = new HashMap<Integer, Integer>();
private int childSpacing = 0;
private int activePageIndex = 1;
private float oldX = 0f;
private float oldY = 0f;
private boolean firstScroll = true;
public PagerInfinite(Context context, AttributeSet attrs) {
super(context, attrs);
this.contents = new LinearLayout(context);
this.contents.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT));
this.addView(this.contents);
setVerticalScrollBarEnabled(false);
setHorizontalScrollBarEnabled(false);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
for (int i = 0; i < this.contents.getChildCount(); i++) {
View child = this.contents.getChildAt(i);
int width = child.getWidth();
if(width != 0) {
this.childWidths.put(i, width);
}
}
if(this.childWidths.size() > 0 && this.firstScroll) {
this.smoothScrollTo(this.getActivePageOffset(), 0);
this.firstScroll = false;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
#Override
protected float getLeftFadingEdgeStrength() {
return 0.0f;
}
#Override
protected float getRightFadingEdgeStrength() {
return 0.0f;
}
public void addPage(View child) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(0, 0, this.childSpacing, 0);
child.setLayoutParams(params);
if(this.contents.getChildCount() <= 1) {
this.contents.addView(child);
} else if(this.contents.getChildCount() <= 2) {
this.contents.addView(child, 0);
} else {
View last = this.contents.getChildAt(0);
this.contents.removeView(last);
this.contents.addView(last);
this.contents.addView(child, 0);
}
this.contents.requestLayout();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = super.onTouchEvent(event);
switch(event.getAction()) {
case(MotionEvent.ACTION_DOWN):
this.oldX = event.getX();
this.oldY = event.getY();
break;
case(MotionEvent.ACTION_UP):
float newX = event.getX();
float newY = event.getY();
float deltaX = newX - this.oldX;
float deltaY = newY - this.oldY;
// Use deltaX and deltaY to determine the direction
if(Math.abs(deltaX) > Math.abs(deltaY)) {
if(deltaX > 0) {
// right
if(this.activePageIndex <= 1) {
this.buildLeft();
} else {
this.activePageIndex -= 1;
}
} else {
// left
if(this.activePageIndex >= this.contents.getChildCount() - 2) {
this.buildRight();
} else {
this.activePageIndex += 1;
}
}
}
this.smoothScrollTo(this.getActivePageOffset(), 0);
break;
}
return result;
}
private void buildLeft() {
View view = this.contents.getChildAt(this.contents.getChildCount() - 1);
this.contents.removeView(view);
this.contents.addView(view, 0);
}
private void buildRight() {
View view = this.contents.getChildAt(0);
this.contents.removeView(view);
this.contents.addView(view);
}
private int getActivePageOffset() {
Log.d(LCHApplication.TAG, "ActiveIndex = " + this.activePageIndex);
if(this.activePageIndex == 0) {
return 0;
}
if(this.activePageIndex == this.contents.getChildCount() - 1) {
return this.contents.getWidth();
}
int offset = 0;
for(Map.Entry<Integer, Integer> entry : this.childWidths.entrySet()) {
if(entry.getKey() < this.activePageIndex) {
offset += entry.getValue() + this.childSpacing;
} else {
break;
}
}
offset += (this.childWidths.get(this.activePageIndex) / 2);
offset -= (LCHApplication.instance.width / 2);
return offset;
}
public boolean hasPage(View v) {
return this.contents.indexOfChild(v) != -1;
}
public void removePage(View v) {
int index = this.contents.indexOfChild(v);
this.contents.removeView(v);
this.childWidths.remove(index);
}
public int getCurrentPageIndex() {
return this.activePageIndex;
}
public int getPageCount() {
return this.contents.getChildCount();
}
public void removeAllPages() {
this.contents.removeAllViews();
this.childWidths = new HashMap<Integer, Integer>();
}
public void cycle() {
if(this.activePageIndex < this.contents.getChildCount() - 1) {
this.activePageIndex += 1;
} else {
this.activePageIndex = 0;
}
this.smoothScrollTo(this.getActivePageOffset(), 0);
}
public int getChildSpacing() {
return this.childSpacing;
}
public void setChildSpacing(int spacing) {
this.childSpacing = spacing;
}
}

Its too late but I believe my answer may helpful to somebody else who has same issue.
Sample project with infinite pages - with page swipe effect
https://github.com/UdaySravanK/USK_APIs

Related

Select random item in CardView

In this picture, you can see a CardView where each item is displayed one at a time. I have implemented a touch functionality that scrolls through the dataset. I would now like to implement the functionality of choosing an item at random. Here is where the CardView is set:
package com.chiemy.cardview.view;
import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.AccelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ListAdapter;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.view.ViewHelper;
import com.nineoldandroids.view.ViewPropertyAnimator;
/**
* #author chiemy
*
*/
public class CardView extends FrameLayout {
private static final int ITEM_SPACE = 40;
private static final int DEF_MAX_VISIBLE = 4;
private int mMaxVisible = DEF_MAX_VISIBLE;
private int itemSpace = ITEM_SPACE;
private float mTouchSlop;
private ListAdapter mListAdapter;
private int mNextAdapterPosition;
private SparseArray<View> viewHolder = new SparseArray<View>();
private OnCardClickListener mListener;
private int topPosition;
private Rect topRect;
public interface OnCardClickListener {
void onCardClick(View view, int position);
}
public CardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public CardView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CardView(Context context) {
super(context);
init();
}
private void init() {
topRect = new Rect();
ViewConfiguration con = ViewConfiguration.get(getContext());
mTouchSlop = con.getScaledTouchSlop();
}
public void setMaxVisibleCount(int count) {
mMaxVisible = count;
}
public int getMaxVisibleCount() {
return mMaxVisible;
}
public void setItemSpace(int itemSpace) {
this.itemSpace = itemSpace;
}
public int getItemSpace() {
return itemSpace;
}
public ListAdapter getAdapter() {
return mListAdapter;
}
public void setAdapter(ListAdapter adapter) {
if (mListAdapter != null) {
mListAdapter.unregisterDataSetObserver(mDataSetObserver);
}
mNextAdapterPosition = 0;
mListAdapter = adapter;
adapter.registerDataSetObserver(mDataSetObserver);
removeAllViews();
ensureFull();
}
public void setOnCardClickListener(OnCardClickListener listener) {
mListener = listener;
}
private void ensureFull() {
while (mNextAdapterPosition < mListAdapter.getCount()
&& getChildCount() < mMaxVisible) {
int index = mNextAdapterPosition % mMaxVisible;
View convertView = viewHolder.get(index);
final View view = mListAdapter.getView(mNextAdapterPosition,
convertView, this);
view.setOnClickListener(null);
viewHolder.put(index, view);
index = Math.min(mNextAdapterPosition, mMaxVisible - 1);
ViewHelper.setScaleX(view,((mMaxVisible - index - 1) / (float) mMaxVisible) * 0.2f + 0.8f);
int topMargin = (mMaxVisible - index - 1) * itemSpace;
ViewHelper.setTranslationY(view, topMargin);
ViewHelper.setAlpha(view, mNextAdapterPosition == 0 ? 1 : 0.5f);
LayoutParams params = (LayoutParams) view.getLayoutParams();
if (params == null) {
params = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
}
addViewInLayout(view, 0, params);
mNextAdapterPosition += 1;
}
// requestLayout();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int childCount = getChildCount();
int maxHeight = 0;
int maxWidth = 0;
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
this.measureChild(child, widthMeasureSpec, heightMeasureSpec);
int height = child.getMeasuredHeight();
int width = child.getMeasuredWidth();
if (height > maxHeight) {
maxHeight = height;
}
if (width > maxWidth) {
maxWidth = width;
}
}
int desireWidth = widthSize;
int desireHeight = heightSize;
if (widthMode == MeasureSpec.AT_MOST) {
desireWidth = maxWidth + getPaddingLeft() + getPaddingRight();
}
if (heightMode == MeasureSpec.AT_MOST) {
desireHeight = maxHeight + (mMaxVisible - 1) * itemSpace + getPaddingTop() + getPaddingBottom();
}
setMeasuredDimension(desireWidth, desireHeight);
}
#Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
View topView = getChildAt(getChildCount() - 1);
if (topView != null) {
topView.setOnClickListener(listener);
}
}
float downX, downY;
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
if (goDown()) {
downY = -1;
}
break;
}
return super.onTouchEvent(event);
}
/**
* 下移所有视图
*/
private boolean goDown() {
final View topView = getChildAt(getChildCount() - 1);
if(!topView.isEnabled()){
return false;
}
// topView.getHitRect(topRect); 在4.3以前有bug,用以下方法代替
topRect = getHitRect(topRect, topView);
// 如果按下的位置不在顶部视图上,则不移动
if (!topRect.contains((int) downX, (int) downY)) {
return false;
}
topView.setEnabled(false);
ViewPropertyAnimator anim = ViewPropertyAnimator
.animate(topView)
.translationY(
ViewHelper.getTranslationY(topView)
+ topView.getHeight()).alpha(0).scaleX(1)
.setListener(null).setDuration(200);
anim.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
topView.setEnabled(true);
removeView(topView);
ensureFull();
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View view = getChildAt(i);
float scaleX = ViewHelper.getScaleX(view)
+ ((float) 1 / mMaxVisible) * 0.2f;
float tranlateY = ViewHelper.getTranslationY(view)
+ itemSpace;
if (i == count - 1) {
bringToTop(view);
} else {
if ((count == mMaxVisible && i != 0)
|| count < mMaxVisible) {
ViewPropertyAnimator
.animate(view)
.translationY(tranlateY)
.setInterpolator(
new AccelerateInterpolator())
.setListener(null).scaleX(scaleX)
.setDuration(200);
}
}
}
}
});
return true;
}
private void bringToTop(final View view) {
topPosition++;
float scaleX = ViewHelper.getScaleX(view) + ((float) 1 / mMaxVisible)
* 0.2f;
float tranlateY = ViewHelper.getTranslationY(view) + itemSpace;
ViewPropertyAnimator.animate(view).translationY(tranlateY)
.scaleX(scaleX).setDuration(200).alpha(1)
.setInterpolator(new AccelerateInterpolator());
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
float currentY = ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = ev.getX();
downY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
float distance = currentY - downY;
if (distance > mTouchSlop) {
return true;
}
break;
}
return false;
}
public static Rect getHitRect(Rect rect, View child) {
rect.left = child.getLeft();
rect.right = child.getRight();
rect.top = (int) (child.getTop() + ViewHelper.getTranslationY(child));
rect.bottom = (int) (child.getBottom() + ViewHelper
.getTranslationY(child));
return rect;
}
private final DataSetObserver mDataSetObserver = new DataSetObserver() {
#Override
public void onChanged() {
super.onChanged();
}
#Override
public void onInvalidated() {
super.onInvalidated();
}
};
private OnClickListener listener = new OnClickListener() {
#Override
public void onClick(View v) {
if (mListener != null) {
mListener.onCardClick(v, topPosition);
}
}
};
}
Here is my CardView adapter class:
package com.chiemy.cardview.view;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.chiemy.cardview.R;
public abstract class CardAdapter<T> extends BaseCardAdapter {
private final Context mContext;
private ArrayList<T> mData;
public CardAdapter(Context context) {
mContext = context;
mData = new ArrayList<T>();
}
public CardAdapter(Context context, Collection<? extends T> items) {
mContext = context;
mData = new ArrayList<T>(items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
FrameLayout wrapper = (FrameLayout) convertView;
View cardView;
View convertedCardView;
if (wrapper == null) {
wrapper = new FrameLayout(mContext);
wrapper.setBackgroundResource(R.drawable.card_background_shadow);
cardView = getCardView(position, null, wrapper);
wrapper.addView(cardView);
} else {
cardView = wrapper.getChildAt(0);
convertedCardView = getCardView(position, cardView, wrapper);
wrapper.removeView(cardView);
wrapper.addView(convertedCardView);
if (convertedCardView != cardView) {
}
}
return wrapper;
}
protected abstract View getCardView(int position, View convertView, ViewGroup parent);
public void addAll(List<T> items){
mData.addAll(items);
}
#Override
public T getItem(int position) {
return mData.get(position);
}
#Override
public int getCount() {
return mData.size();
}
#Override
public long getItemId(int position) {
return getItem(position).hashCode();
}
public Context getContext() {
return mContext;
}
public void clear(){
if(mData != null){
mData.clear();
}
}
}
Any suggestions on how to achieve this?
To randomise an ArrayList<>, in your case, this would be the shuffling solution, you can use this code:
long seed = System.nanoTime();
Collections.shuffle(list_of_items, new Random(seed));
You will need to set the ArrayList<> back to the CardView and your items will be randomly shuffled. To retrieve a random item, visit this page to learn about getting a random item from an ArrayList<>. See how you go and ask for more help if needed.

How to make Horizontal ListView

I want to make a Horizontal listview, but i don't want to use the library of third-party. So, i try to use PagerAdapter but i can do it.
I don't know how to fix it.
This is my code i use to load photo:
public class GalleryActivity extends AppCompatActivity {
public static final String TAG = "GalleryActivity";
public static final String EXTRA_NAME = "images";
ArrayList<Actor> actors = new ArrayList<>();
private GalleryPagerAdapter _adapter;
#InjectView(R.id.pager) ViewPager _pager;
#InjectView(R.id.thumbnails) LinearLayout _thumbnails;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
ButterKnife.inject(this);
importActor();
_adapter = new GalleryPagerAdapter(this);
_pager.setAdapter(_adapter);
_pager.setOffscreenPageLimit(6);
}
public void importActor(){
Bitmap bitmap = BitmapFactory.decodeResource(GalleryActivity.this.getResources(), R.drawable.nhaphuong);
Bitmap bitmap1 = BitmapFactory.decodeResource(GalleryActivity.this.getResources(),R.drawable.subo);
Bitmap bitmap2 = BitmapFactory.decodeResource(GalleryActivity.this.getResources(),R.drawable.truonggiang);
Actor actor = new Actor(5,"Nhã Phương",bitmap);
Actor actor1 = new Actor(15,"Trường Giang",bitmap2);
Actor actor2 = new Actor(999,"Subo",bitmap1);
actors.add(actor);
actors.add(actor1);
actors.add(actor2);
}
class GalleryPagerAdapter extends PagerAdapter {
Context _context;
LayoutInflater _inflater;
public GalleryPagerAdapter(Context context) {
_context = context;
_inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return actors.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((RelativeLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, final int position) {
View view = _inflater.inflate(R.layout.one_actor, container, false);
container.addView(view);
// Get the border size to show around each image
int borderSize = _thumbnails.getPaddingTop();
// Get the size of the actual thumbnail image
int thumbnailSize = ((FrameLayout.LayoutParams)
_pager.getLayoutParams()).bottomMargin - (borderSize*2);
// Set the thumbnail layout parameters. Adjust as required
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(thumbnailSize, thumbnailSize);
params.setMargins(0, 0, borderSize, 0);
OneActor oneActor = new OneActor();
oneActor.avatar = (ImageView) view.findViewById(R.id.imgActor);
oneActor.name = (TextView) view.findViewById(R.id.tvActorName);
oneActor.cmtCount = (TextView) view.findViewById(R.id.tvCmtCount);
view.setTag(oneActor);
oneActor.avatar.setImageBitmap(actors.get(position).getAvatar());
oneActor.cmtCount.setText(actors.get(position).getCmtcout() + "");
oneActor.name.setText(actors.get(position).getName());
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
class OneActor{
ImageView avatar;
TextView name, cmtCount;
}
}
This is my xml file:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="72dp"
android:layout_gravity="center">
<LinearLayout
android:id="#+id/thumbnails"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingTop="2dp"/>
</HorizontalScrollView>
Tell my how to fix it or give me a tutoral please!
You have to use RecyclerView if you dont have to use it then use HorizontalListView. see below code for HorizontalListView
HorizontalListView.java
import java.util.LinkedList;
import java.util.Queue;
import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.Scroller;
public class HorizontalListView extends AdapterView<ListAdapter> {
public boolean mAlwaysOverrideTouch = true;
protected ListAdapter mAdapter;
private int mLeftViewIndex = -1;
private int mRightViewIndex = 0;
protected int mCurrentX;
protected int mNextX;
private int mMaxX = Integer.MAX_VALUE;
private int mDisplayOffset = 0;
protected Scroller mScroller;
private GestureDetector mGesture;
private Queue<View> mRemovedViewQueue = new LinkedList<View>();
private OnItemSelectedListener mOnItemSelected;
private OnItemClickListener mOnItemClicked;
public HorizontalListView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
private void initView() {
mLeftViewIndex = -1;
mRightViewIndex = 0;
mDisplayOffset = 0;
mCurrentX = 0;
mNextX = 0;
mMaxX = Integer.MAX_VALUE;
mScroller = new Scroller(getContext());
mGesture = new GestureDetector(getContext(), mOnGesture);
}
#Override
public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener) {
mOnItemSelected = listener;
Log.v("log_tag", "Message is set On Clicked");
}
#Override
public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
mOnItemClicked = listener;
Log.v("log_tag", "Set on Item Clicked");
}
private DataSetObserver mDataObserver=new DataSetObserver(){
#Override public void onChanged(){
// TODO Auto-generated method stub
super.onChanged();}
#Override public void onInvalidated(){
// TODO Auto-generated method stub
super.onInvalidated();}
};
#Override
public ListAdapter getAdapter() {
return mAdapter;
}
#Override
public View getSelectedView() {
// TODO: implement
return null;
}
#Override
public void setAdapter(ListAdapter adapter) {
if (mAdapter != null) {
mAdapter.unregisterDataSetObserver(mDataObserver);
}
mAdapter = adapter;
mAdapter.registerDataSetObserver(mDataObserver);
initView();
removeAllViewsInLayout();
requestLayout();
}
#Override
public void setSelection(int position) {
// TODO: implement
}
private void addAndMeasureChild(final View child, int viewPos) {
LayoutParams params = child.getLayoutParams();
if (params == null) {
params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
}
addViewInLayout(child, viewPos, params, true);
child.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
}
#Override
protected synchronized void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mAdapter == null) {
return;
}
if (mScroller.computeScrollOffset()) {
int scrollx = mScroller.getCurrX();
mNextX = scrollx;
}
if (mNextX < 0) {
mNextX = 0;
mScroller.forceFinished(true);
}
if (mNextX > mMaxX) {
mNextX = mMaxX;
mScroller.forceFinished(true);
}
int dx = mCurrentX - mNextX;
removeNonVisibleItems(dx);
fillList(dx);
positionItems(dx);
mCurrentX = mNextX;
if (!mScroller.isFinished()) {
post(new Runnable() {
#Override
public void run() {
requestLayout();
}
});
}
}
private void fillList(final int dx) {
int edge = 0;
View child = getChildAt(getChildCount() - 1);
if (child != null) {
edge = child.getRight();
}
fillListRight(edge, dx);
edge = 0;
child = getChildAt(0);
if (child != null) {
edge = child.getLeft();
}
fillListLeft(edge, dx);
}
private void fillListRight(int rightEdge, final int dx) {
while (rightEdge + dx < getWidth() && mRightViewIndex < mAdapter.getCount()) {
View child = mAdapter.getView(mRightViewIndex, mRemovedViewQueue.poll(), this);
addAndMeasureChild(child, -1);
rightEdge += child.getMeasuredWidth();
if (mRightViewIndex == mAdapter.getCount() - 1) {
mMaxX = mCurrentX + rightEdge - getWidth();
}
mRightViewIndex++;
}
}
private void fillListLeft(int leftEdge, final int dx) {
while (leftEdge + dx > 0 && mLeftViewIndex >= 0) {
View child = mAdapter.getView(mLeftViewIndex, mRemovedViewQueue.poll(), this);
addAndMeasureChild(child, 0);
leftEdge -= child.getMeasuredWidth();
mLeftViewIndex--;
mDisplayOffset -= child.getMeasuredWidth();
}
}
private void removeNonVisibleItems(final int dx) {
View child = getChildAt(0);
while (child != null && child.getRight() + dx <= 0) {
mDisplayOffset += child.getMeasuredWidth();
mRemovedViewQueue.offer(child);
removeViewInLayout(child);
mLeftViewIndex++;
child = getChildAt(0);
}
child = getChildAt(getChildCount() - 1);
while (child != null && child.getLeft() + dx >= getWidth()) {
mRemovedViewQueue.offer(child);
removeViewInLayout(child);
mRightViewIndex--;
child = getChildAt(getChildCount() - 1);
}
}
private void positionItems(final int dx) {
if (getChildCount() > 0) {
mDisplayOffset += dx;
int left = mDisplayOffset;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
int childWidth = child.getMeasuredWidth();
child.layout(left, 0, left + childWidth, child.getMeasuredHeight());
left += childWidth;
}
}
}
public synchronized void scrollTo(int x) {
mScroller.startScroll(mNextX, 0, x - mNextX, 0);
requestLayout();
}
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean handled = mGesture.onTouchEvent(ev);
return super.dispatchTouchEvent(ev);
}
protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
synchronized (HorizontalListView.this) {
mScroller.fling(mNextX, 0, (int) -velocityX, 0, 0, mMaxX, 0, 0);
}
requestLayout();
return true;
}
protected boolean onDown(MotionEvent e) {
mScroller.forceFinished(true);
return true;
}
private OnGestureListener mOnGesture=new GestureDetector.SimpleOnGestureListener(){
#Override public boolean onDown(MotionEvent e){return HorizontalListView.this.onDown(e);}
#Override public boolean onFling(MotionEvent e1,MotionEvent e2,float velocityX,float velocityY){return HorizontalListView.this.onFling(e1,e2,velocityX,velocityY);}
#Override public boolean onScroll(MotionEvent e1,MotionEvent e2,float distanceX,float distanceY){
synchronized(HorizontalListView.this){mNextX+=(int)distanceX;}requestLayout();
return true;}
#Override public boolean onSingleTapConfirmed(MotionEvent e){Rect viewRect=new Rect();for(int i=0;i<getChildCount();i++){View child=getChildAt(i);int left=child.getLeft();int right=child.getRight();int top=child.getTop();int bottom=child.getBottom();viewRect.set(left,top,right,bottom);if(viewRect.contains((int)e.getX(),(int)e.getY())){if(mOnItemClicked!=null){mOnItemClicked.onItemClick(HorizontalListView.this,child,mLeftViewIndex+1+i,0);}if(mOnItemSelected!=null){mOnItemSelected.onItemSelected(HorizontalListView.this,child,mLeftViewIndex+1+i,0);}break;}
}return true;}
};
}
Use in xml as listview as like
<youpackage.HorizantalListView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Better to use RecyclerView. it worked as HorizontalListView also and it does not require any third party library.
for this you need to do something like this
LinearLayoutManager layoutManager
= new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView myList = (RecyclerView) findViewById(R.id.my_recycler_view);
myList.setLayoutManager(layoutManager);

Unable to set visibility of any relative layout in a View Group in Android

I am using a floating action button in my activity. I have created a related layout with a black opacity background. I want it to appear when the floating action button is clicked. The relative layout will appear behind the action button to make it look prominent.
Here is my xml layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:fab="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="com.paaltao.activity.HomeActivity">
<include
android:id="#+id/app_bar"
layout="#layout/app_bar" />
<it.neokree.materialtabs.MaterialTabHost
android:id="#+id/materialTabHost"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_below="#+id/app_bar"
app:accentColor="#color/greenMaterial"
app:hasIcons="true"
app:primaryColor="#color/primaryColor"
app:textColor="#color/white" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/materialTabHost" />
<RelativeLayout
android:id="#+id/white_opacity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/materialTabHost"
android:background="#color/black80"
android:visibility="gone" />
<com.paaltao.classes.FloatingActionsMenu
android:id="#+id/multiple_actions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_gravity="end"
fab:fab_addButtonColorPressed="#color/white_pressed"
fab:fab_addButtonPlusIconColor="#color/white"
fab:fab_labelStyle="#style/menu_labels_style"
app:fab_addButtonColorNormal="#color/primaryColor">
<com.paaltao.classes.FloatingActionButton
android:id="#+id/action_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
fab:fab_colorNormal="#color/white"
fab:fab_colorPressed="#color/white_pressed"
fab:fab_title="Action B" />
</com.paaltao.classes.FloatingActionsMenu>
</RelativeLayout>
I am basically trying to set visibility of the relative layout to View.VISIBLE in the floating action menu class which extends a view group. Now I am getting null pointer exception when I am setting the visibility as View.VISIBLE in the button's onClick event.
Here is my Java Code :
package com.paaltao.classes;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.paaltao.R;
import java.util.zip.Inflater;
public class FloatingActionsMenu extends ViewGroup {
public static final int EXPAND_UP = 0;
public static final int EXPAND_DOWN = 1;
public static final int EXPAND_LEFT = 2;
public static final int EXPAND_RIGHT = 3;
private static final int ANIMATION_DURATION = 300;
private static final float COLLAPSED_PLUS_ROTATION = 0f;
private static final float EXPANDED_PLUS_ROTATION = 90f + 45f;
private int mAddButtonPlusColor;
private int mAddButtonColorNormal;
private int mAddButtonColorPressed;
private int mAddButtonSize;
private boolean mAddButtonStrokeVisible;
private int mExpandDirection;
private int mButtonSpacing;
private int mLabelsMargin;
private int mLabelsVerticalOffset;
private boolean mExpanded;
private AnimatorSet mExpandAnimation = new AnimatorSet().setDuration(ANIMATION_DURATION);
private AnimatorSet mCollapseAnimation = new AnimatorSet().setDuration(ANIMATION_DURATION);
private AddFloatingActionButton mAddButton;
private RotatingDrawable mRotatingDrawable;
private int mMaxButtonWidth;
private int mMaxButtonHeight;
private int mLabelsStyle;
private int mButtonsCount;
private OnFloatingActionsMenuUpdateListener mListener;
private RelativeLayout whiteOverlay;
public interface OnFloatingActionsMenuUpdateListener {
void onMenuExpanded();
void onMenuCollapsed();
}
public FloatingActionsMenu(Context context) {
this(context, null);
}
public FloatingActionsMenu(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public FloatingActionsMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
private void init(Context context, AttributeSet attributeSet) {
mButtonSpacing = (int) (getResources().getDimension(R.dimen.fab_actions_spacing) - getResources().getDimension(R.dimen.fab_shadow_radius) - getResources().getDimension(R.dimen.fab_shadow_offset));
mLabelsMargin = getResources().getDimensionPixelSize(R.dimen.fab_labels_margin);
mLabelsVerticalOffset = getResources().getDimensionPixelSize(R.dimen.fab_shadow_offset);
TypedArray attr = context.obtainStyledAttributes(attributeSet, R.styleable.FloatingActionsMenu, 0, 0);
mAddButtonPlusColor = attr.getColor(R.styleable.FloatingActionsMenu_fab_addButtonPlusIconColor, getColor(android.R.color.white));
mAddButtonColorNormal = attr.getColor(R.styleable.FloatingActionsMenu_fab_addButtonColorNormal, getColor(android.R.color.holo_blue_dark));
mAddButtonColorPressed = attr.getColor(R.styleable.FloatingActionsMenu_fab_addButtonColorPressed, getColor(android.R.color.holo_blue_light));
mAddButtonSize = attr.getInt(R.styleable.FloatingActionsMenu_fab_addButtonSize, FloatingActionButton.SIZE_NORMAL);
mAddButtonStrokeVisible = attr.getBoolean(R.styleable.FloatingActionsMenu_fab_addButtonStrokeVisible, true);
mExpandDirection = attr.getInt(R.styleable.FloatingActionsMenu_fab_expandDirection, EXPAND_UP);
mLabelsStyle = attr.getResourceId(R.styleable.FloatingActionsMenu_fab_labelStyle, 0);
attr.recycle();
if (mLabelsStyle != 0 && expandsHorizontally()) {
throw new IllegalStateException("Action labels in horizontal expand orientation is not supported.");
}
createAddButton(context);
}
public void setOnFloatingActionsMenuUpdateListener(OnFloatingActionsMenuUpdateListener listener) {
mListener = listener;
}
private boolean expandsHorizontally() {
return mExpandDirection == EXPAND_LEFT || mExpandDirection == EXPAND_RIGHT;
}
private static class RotatingDrawable extends LayerDrawable {
public RotatingDrawable(Drawable drawable) {
super(new Drawable[] { drawable });
}
private float mRotation;
#SuppressWarnings("UnusedDeclaration")
public float getRotation() {
return mRotation;
}
#SuppressWarnings("UnusedDeclaration")
public void setRotation(float rotation) {
mRotation = rotation;
invalidateSelf();
}
#Override
public void draw(Canvas canvas) {
canvas.save();
canvas.rotate(mRotation, getBounds().centerX(), getBounds().centerY());
super.draw(canvas);
canvas.restore();
}
}
private void createAddButton(Context context) {
mAddButton = new AddFloatingActionButton(context) {
#Override
void updateBackground() {
mPlusColor = mAddButtonPlusColor;
mColorNormal = mAddButtonColorNormal;
mColorPressed = mAddButtonColorPressed;
mStrokeVisible = mAddButtonStrokeVisible;
super.updateBackground();
}
#Override
Drawable getIconDrawable() {
final RotatingDrawable rotatingDrawable = new RotatingDrawable(super.getIconDrawable());
mRotatingDrawable = rotatingDrawable;
final OvershootInterpolator interpolator = new OvershootInterpolator();
final ObjectAnimator collapseAnimator = ObjectAnimator.ofFloat(rotatingDrawable, "rotation", EXPANDED_PLUS_ROTATION, COLLAPSED_PLUS_ROTATION);
final ObjectAnimator expandAnimator = ObjectAnimator.ofFloat(rotatingDrawable, "rotation", COLLAPSED_PLUS_ROTATION, EXPANDED_PLUS_ROTATION);
collapseAnimator.setInterpolator(interpolator);
expandAnimator.setInterpolator(interpolator);
mExpandAnimation.play(expandAnimator);
mCollapseAnimation.play(collapseAnimator);
return rotatingDrawable;
}
};
mAddButton.setId(R.id.fab_expand_menu_button);
mAddButton.setSize(mAddButtonSize);
mAddButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
toggle();
// updateBackground();
}
});
addView(mAddButton, super.generateDefaultLayoutParams());
}
// public void updateBackground(){
// whiteOverlay = (RelativeLayout)findViewById(R.id.white_opacity);
// whiteOverlay.setVisibility(View.VISIBLE);
// }
public void addButton(FloatingActionButton button) {
addView(button, mButtonsCount - 1);
mButtonsCount++;
if (mLabelsStyle != 0) {
createLabels();
}
}
public void removeButton(FloatingActionButton button) {
removeView(button.getLabelView());
removeView(button);
mButtonsCount--;
}
private int getColor(#ColorRes int id) {
return getResources().getColor(id);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureChildren(widthMeasureSpec, heightMeasureSpec);
int width = 0;
int height = 0;
mMaxButtonWidth = 0;
mMaxButtonHeight = 0;
int maxLabelWidth = 0;
for (int i = 0; i < mButtonsCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
switch (mExpandDirection) {
case EXPAND_UP:
case EXPAND_DOWN:
mMaxButtonWidth = Math.max(mMaxButtonWidth, child.getMeasuredWidth());
height += child.getMeasuredHeight();
break;
case EXPAND_LEFT:
case EXPAND_RIGHT:
width += child.getMeasuredWidth();
mMaxButtonHeight = Math.max(mMaxButtonHeight, child.getMeasuredHeight());
break;
}
if (!expandsHorizontally()) {
TextView label = (TextView) child.getTag(R.id.fab_label);
if (label != null) {
maxLabelWidth = Math.max(maxLabelWidth, label.getMeasuredWidth());
}
}
}
if (!expandsHorizontally()) {
width = mMaxButtonWidth + (maxLabelWidth > 0 ? maxLabelWidth + mLabelsMargin : 0);
} else {
height = mMaxButtonHeight;
}
switch (mExpandDirection) {
case EXPAND_UP:
case EXPAND_DOWN:
height += mButtonSpacing * (getChildCount() - 1);
height = adjustForOvershoot(height);
break;
case EXPAND_LEFT:
case EXPAND_RIGHT:
width += mButtonSpacing * (getChildCount() - 1);
width = adjustForOvershoot(width);
break;
}
setMeasuredDimension(width, height);
}
private int adjustForOvershoot(int dimension) {
return dimension * 12 / 10;
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
switch (mExpandDirection) {
case EXPAND_UP:
case EXPAND_DOWN:
boolean expandUp = mExpandDirection == EXPAND_UP;
int addButtonY = expandUp ? b - t - mAddButton.getMeasuredHeight() : 0;
// Ensure mAddButton is centered on the line where the buttons should be
int addButtonLeft = r - l - mMaxButtonWidth + (mMaxButtonWidth - mAddButton.getMeasuredWidth()) / 2;
mAddButton.layout(addButtonLeft, addButtonY, addButtonLeft + mAddButton.getMeasuredWidth(), addButtonY + mAddButton.getMeasuredHeight());
int labelsRight = r - l - mMaxButtonWidth - mLabelsMargin;
int nextY = expandUp ?
addButtonY - mButtonSpacing :
addButtonY + mAddButton.getMeasuredHeight() + mButtonSpacing;
for (int i = mButtonsCount - 1; i >= 0; i--) {
final View child = getChildAt(i);
if (child == mAddButton || child.getVisibility() == GONE) continue;
int childX = addButtonLeft + (mAddButton.getMeasuredWidth() - child.getMeasuredWidth()) / 2;
int childY = expandUp ? nextY - child.getMeasuredHeight() : nextY;
child.layout(childX, childY, childX + child.getMeasuredWidth(), childY + child.getMeasuredHeight());
float collapsedTranslation = addButtonY - childY;
float expandedTranslation = 0f;
child.setTranslationY(mExpanded ? expandedTranslation : collapsedTranslation);
child.setAlpha(mExpanded ? 1f : 0f);
LayoutParams params = (LayoutParams) child.getLayoutParams();
params.mCollapseDir.setFloatValues(expandedTranslation, collapsedTranslation);
params.mExpandDir.setFloatValues(collapsedTranslation, expandedTranslation);
params.setAnimationsTarget(child);
View label = (View) child.getTag(R.id.fab_label);
if (label != null) {
int labelLeft = labelsRight - label.getMeasuredWidth();
int labelTop = childY - mLabelsVerticalOffset + (child.getMeasuredHeight() - label.getMeasuredHeight()) / 2;
label.layout(labelLeft, labelTop, labelsRight, labelTop + label.getMeasuredHeight());
label.setTranslationY(mExpanded ? expandedTranslation : collapsedTranslation);
label.setAlpha(mExpanded ? 1f : 0f);
LayoutParams labelParams = (LayoutParams) label.getLayoutParams();
labelParams.mCollapseDir.setFloatValues(expandedTranslation, collapsedTranslation);
labelParams.mExpandDir.setFloatValues(collapsedTranslation, expandedTranslation);
labelParams.setAnimationsTarget(label);
}
nextY = expandUp ?
childY - mButtonSpacing :
childY + child.getMeasuredHeight() + mButtonSpacing;
}
break;
case EXPAND_LEFT:
case EXPAND_RIGHT:
boolean expandLeft = mExpandDirection == EXPAND_LEFT;
int addButtonX = expandLeft ? r - l - mAddButton.getMeasuredWidth() : 0;
// Ensure mAddButton is centered on the line where the buttons should be
int addButtonTop = b - t - mMaxButtonHeight + (mMaxButtonHeight - mAddButton.getMeasuredHeight()) / 2;
mAddButton.layout(addButtonX, addButtonTop, addButtonX + mAddButton.getMeasuredWidth(), addButtonTop + mAddButton.getMeasuredHeight());
int nextX = expandLeft ?
addButtonX - mButtonSpacing :
addButtonX + mAddButton.getMeasuredWidth() + mButtonSpacing;
for (int i = mButtonsCount - 1; i >= 0; i--) {
final View child = getChildAt(i);
if (child == mAddButton || child.getVisibility() == GONE) continue;
int childX = expandLeft ? nextX - child.getMeasuredWidth() : nextX;
int childY = addButtonTop + (mAddButton.getMeasuredHeight() - child.getMeasuredHeight()) / 2;
child.layout(childX, childY, childX + child.getMeasuredWidth(), childY + child.getMeasuredHeight());
float collapsedTranslation = addButtonX - childX;
float expandedTranslation = 0f;
child.setTranslationX(mExpanded ? expandedTranslation : collapsedTranslation);
child.setAlpha(mExpanded ? 1f : 0f);
LayoutParams params = (LayoutParams) child.getLayoutParams();
params.mCollapseDir.setFloatValues(expandedTranslation, collapsedTranslation);
params.mExpandDir.setFloatValues(collapsedTranslation, expandedTranslation);
params.setAnimationsTarget(child);
nextX = expandLeft ?
childX - mButtonSpacing :
childX + child.getMeasuredWidth() + mButtonSpacing;
}
break;
}
}
#Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(super.generateDefaultLayoutParams());
}
#Override
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(super.generateLayoutParams(attrs));
}
#Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(super.generateLayoutParams(p));
}
#Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return super.checkLayoutParams(p);
}
private static Interpolator sExpandInterpolator = new OvershootInterpolator();
private static Interpolator sCollapseInterpolator = new DecelerateInterpolator(3f);
private static Interpolator sAlphaExpandInterpolator = new DecelerateInterpolator();
private class LayoutParams extends ViewGroup.LayoutParams {
private ObjectAnimator mExpandDir = new ObjectAnimator();
private ObjectAnimator mExpandAlpha = new ObjectAnimator();
private ObjectAnimator mCollapseDir = new ObjectAnimator();
private ObjectAnimator mCollapseAlpha = new ObjectAnimator();
private boolean animationsSetToPlay;
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
mExpandDir.setInterpolator(sExpandInterpolator);
mExpandAlpha.setInterpolator(sAlphaExpandInterpolator);
mCollapseDir.setInterpolator(sCollapseInterpolator);
mCollapseAlpha.setInterpolator(sCollapseInterpolator);
mCollapseAlpha.setProperty(View.ALPHA);
mCollapseAlpha.setFloatValues(1f, 0f);
mExpandAlpha.setProperty(View.ALPHA);
mExpandAlpha.setFloatValues(0f, 1f);
switch (mExpandDirection) {
case EXPAND_UP:
case EXPAND_DOWN:
mCollapseDir.setProperty(View.TRANSLATION_Y);
mExpandDir.setProperty(View.TRANSLATION_Y);
break;
case EXPAND_LEFT:
case EXPAND_RIGHT:
mCollapseDir.setProperty(View.TRANSLATION_X);
mExpandDir.setProperty(View.TRANSLATION_X);
break;
}
}
public void setAnimationsTarget(View view) {
mCollapseAlpha.setTarget(view);
mCollapseDir.setTarget(view);
mExpandAlpha.setTarget(view);
mExpandDir.setTarget(view);
// Now that the animations have targets, set them to be played
if (!animationsSetToPlay) {
mCollapseAnimation.play(mCollapseAlpha);
mCollapseAnimation.play(mCollapseDir);
mExpandAnimation.play(mExpandAlpha);
mExpandAnimation.play(mExpandDir);
animationsSetToPlay = true;
}
}
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
bringChildToFront(mAddButton);
mButtonsCount = getChildCount();
if (mLabelsStyle != 0) {
createLabels();
}
}
private void createLabels() {
Context context = new ContextThemeWrapper(getContext(), mLabelsStyle);
for (int i = 0; i < mButtonsCount; i++) {
FloatingActionButton button = (FloatingActionButton) getChildAt(i);
String title = button.getTitle();
if (button == mAddButton || title == null ||
button.getTag(R.id.fab_label) != null) continue;
TextView label = new TextView(context);
label.setText(button.getTitle());
addView(label);
button.setTag(R.id.fab_label, label);
}
}
public void collapse() {
if (mExpanded) {
mExpanded = false;
mCollapseAnimation.start();
mExpandAnimation.cancel();
if (mListener != null) {
mListener.onMenuCollapsed();
}
}
}
public void toggle() {
if (mExpanded) {
collapse();
} else {
expand();
}
}
public void expand() {
if (!mExpanded) {
mExpanded = true;
mCollapseAnimation.cancel();
mExpandAnimation.start();
if (mListener != null) {
mListener.onMenuExpanded();
}
}
}
public boolean isExpanded() {
return mExpanded;
}
#Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.mExpanded = mExpanded;
return savedState;
}
#Override
public void onRestoreInstanceState(Parcelable state) {
if (state instanceof SavedState) {
SavedState savedState = (SavedState) state;
mExpanded = savedState.mExpanded;
if (mRotatingDrawable != null) {
mRotatingDrawable.setRotation(mExpanded ? EXPANDED_PLUS_ROTATION : COLLAPSED_PLUS_ROTATION);
}
super.onRestoreInstanceState(savedState.getSuperState());
} else {
super.onRestoreInstanceState(state);
}
}
public static class SavedState extends BaseSavedState {
public boolean mExpanded;
public SavedState(Parcelable parcel) {
super(parcel);
}
private SavedState(Parcel in) {
super(in);
mExpanded = in.readInt() == 1;
}
#Override
public void writeToParcel(#NonNull Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(mExpanded ? 1 : 0);
}
public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
#Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
#Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
Please Help.
If I understand correctly, the code causing the problem is the one commented, otherwise this line :
whiteOverlay.setVisibility(View.VISIBLE);
You are trying to access your RelativeLayout (R.id.white_opacity) through your FloatingActionsMenu view :
whiteOverlay = (RelativeLayout)findViewById(R.id.white_opacity);
But R.id.white_opacity is a member of your HomeActivity view.
So it's normal that this line returns a null pointer since it doesn't have any member named like this.
Try do find a way to access your HomeActivity view and then call "findViewById()" on it.
If "context" is indeed this HomeActivity, then pass the argument to the updateBackground() method (or set context as a class member) and try somthing like that :
whiteOverlay = ((Activity)context).findViewById(R.id.white_opacity);
Regards.

Storing the Activity's state when the screen turns off

I'm developing an android game, trying to store the character's coordinates. I'm using the onSaveInstanceState and onRestoreInstanceState methods. But when I tested the coordinates get's changed.
So it loads the correct value but after that it saves a bad number then it loads this bad value.
Class1
package hu.cig.vob;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import cug.hu.vob.R;
public class Level extends Activity {
private LevelView lv;
private LinearLayout linearL;
private Button left, right, jump, fire;
private mListener l = new mListener();
//Konstansok az activity allapotanak mentesehez
private String playerX = "PlayerX",playerY="PlayerY",playerH="PlayerH";
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.level_layout);
final ImageView healthBar = (ImageView) findViewById(R.id.life_view);
Drawable d = getResources().getDrawable(R.drawable.main_screen_bg);
linearL = (LinearLayout) findViewById(R.id.linear_layout);
linearL.setBackgroundDrawable(d);
lv = new LevelView(getApplicationContext(), getIntent().getIntExtra(
MainActivity.LEVEL_EXTRA, 0), getWindowManager());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT);
lv.setLayoutParams(params);
linearL.addView(lv, 0);
left = (Button) findViewById(R.id.left);
right = (Button) findViewById(R.id.right);
jump = (Button) findViewById(R.id.jump);
fire = (Button) findViewById(R.id.fire);
left.setOnTouchListener(l);
right.setOnTouchListener(l);
jump.setOnTouchListener(l);
fire.setOnTouchListener(l);
lv.setOnClickListener(new OnClickListener() {
// Game over screen esetén kilép
#Override
public void onClick(View v) {
if (lv.getGameState()) {
finish();
}
}
});
// Életcsik frissitése az életnek megfelelően
new Thread() {
#Override
public void run() {
while (true) {
if (lv.getRobot().getHealth() <= 0) {
runOnUiThread(new Runnable() {
#Override
public void run() {
healthBar.setImageResource(R.drawable.battery5);
}
});
} else if (lv.getRobot().getHealth() <= 25) {
runOnUiThread(new Runnable() {
#Override
public void run() {
healthBar.setImageResource(R.drawable.battery4);
}
});
} else if (lv.getRobot().getHealth() <= 50) {
runOnUiThread(new Runnable() {
#Override
public void run() {
healthBar.setImageResource(R.drawable.battery3);
}
});
} else if (lv.getRobot().getHealth() <= 75) {
runOnUiThread(new Runnable() {
#Override
public void run() {
healthBar.setImageResource(R.drawable.battery2);
}
});
}else if(lv.getRobot().getHealth() >= 75){
runOnUiThread(new Runnable() {
#Override
public void run() {
healthBar.setImageResource(R.drawable.battery);
}
});
}
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
#Override
protected void onPause() {
overridePendingTransition(0, 0);
super.onPause();
}
// TODO:
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
lv.getRobot().setX(savedInstanceState.getInt(playerX));
lv.getRobot().setY(savedInstanceState.getInt(playerY));
Log.d("LoL","Loaded y:"+savedInstanceState.getInt(playerY));
lv.getRobot().setHealth(savedInstanceState.getInt(playerH));
super.onRestoreInstanceState(savedInstanceState);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt(playerX , lv.getRobot().getX());
outState.putInt(playerY, lv.getRobot().getY());
Log.d("LoL","Saved y:"+lv.getRobot().getY());
outState.putInt(playerH, lv.getRobot().getHealth() );
super.onSaveInstanceState(outState);
}
// iránygombok kezelése
private class mListener implements OnTouchListener {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
switch (v.getId()) {
case R.id.left:
lv.getRobot().moveLeft();
break;
case R.id.right:
lv.getRobot().moveRight();
break;
case R.id.jump:
lv.getRobot().jump();
break;
case R.id.fire:
lv.getRobot().shot();
break;
}
break;
case MotionEvent.ACTION_UP:
switch (v.getId()) {
case R.id.left:
lv.getRobot().stopMovingLeft();
break;
case R.id.right:
lv.getRobot().stopMovingRight();
break;
case R.id.fire:
lv.getRobot()._shot();
break;
}
break;
}
return true;
}
}
}
class2
package hu.cig.vob;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import cug.hu.vob.R;
public class Robot {
private Bitmap icon, currIcon, iconShot;
private int x, y, speedX = 0, speedY = 0, health = 100;
private final int MOVESPEED = 3, JumpSpeed = 15;
private boolean isMovingLeft = false, isMovingRight = false,
isFalling = true, isJumping = false, canJump = true;
private Rect bottom, horizontal;
private Context context;
private List<Bullet> bullets = Collections
.synchronizedList(new ArrayList<Bullet>());
public Robot(int in_x, int in_y, Bitmap i, float sc, Context c) {
context = c;
icon = i;
currIcon = icon;
iconShot = BitmapFactory.decodeResource(c.getResources(),
R.drawable.shot_right);
x = in_x * (icon.getWidth()/2);
y = in_y * (icon.getHeight()/2);
y = (int) (sc - y);
// for colliding
horizontal = new Rect((int) (x + icon.getWidth() * (31.5 / 100)),
y + 5, (int) (x + icon.getWidth() - icon.getWidth()
* (31.5 / 100)), y + icon.getHeight() - 5);
bottom = new Rect((int) (x + icon.getWidth() * (31.5 / 100) + 5), y
+ icon.getHeight() - 10, (int) (x + icon.getWidth()
- icon.getWidth() * (31.5 / 100) - 5), y + icon.getHeight());
}
public void update(List<Block> blocks) {
int oldX = x, oldY = y;
if (!(x + speedX < 0 || x + speedX > LevelView.intScreenWidth)) {
x += speedX;
}
updateRect();
for (int i = 0; i < blocks.size(); i++) {
if (horizontal.intersect(blocks.get(i).getRect())) {
stopMovingRight();
stopMovingLeft();
x = oldX;
updateRect();
}
}
if (bullets.size() > 0) {
Iterator<Bullet> it = bullets.iterator();
while (it.hasNext()) {
Bullet b = it.next();
if (b.getCx() > LevelView.screenWidth) {
it.remove();
} else {
b.update();
}
Iterator<Block> itt = blocks.iterator();
while (itt.hasNext()) {
Block bb = itt.next();
if (bb.getRect().intersect(b.getRect())) {
it.remove();
}
}
}
}
// #graviti"
if (isJumping) {
y -= speedY;
speedY--;
if (speedY == 0) {
isFalling = true;
isJumping = false;
}
updateRect();
}
if (isFalling) {
y += JumpSpeed - 5;
canJump = false;
updateRect();
}
for (Block b : blocks) {
if (bottom.intersect(b.getRect())) {
y = oldY;
updateRect();
canJump = true;
}
}
}
private void updateRect() {
horizontal = new Rect((int) (x + icon.getWidth() * (31.5 / 100)),
y + 10, (int) (x + icon.getWidth() - icon.getWidth()
* (31.5 / 100)), y + icon.getHeight() - 10);
bottom = new Rect((int) (x + icon.getWidth() * (31.5 / 100) + 5), y
+ icon.getHeight() - 10, (int) (x + icon.getWidth()
- icon.getWidth() * (31.5 / 100) - 5), y + icon.getHeight() - 2);
}
public void moveLeft() {
speedX = -MOVESPEED;
isMovingLeft = true;
}
public void moveRight() {
speedX = MOVESPEED;
isMovingRight = true;
}
public void stopMovingLeft() {
isMovingLeft = false;
stop();
}
public void stopMovingRight() {
isMovingRight = false;
stop();
}
public void stop() {
if (isMovingRight == false && isMovingLeft == false) {
speedX = 0;
}
if (isMovingRight == true && isMovingLeft == false) {
moveRight();
}
if (isMovingRight == false && isMovingLeft == true) {
moveLeft();
}
}
public Bitmap getIcon() {
return currIcon;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getSpeed() {
return speedX;
}
public boolean isMovingLeft() {
return isMovingLeft;
}
public boolean isMovingRight() {
return isMovingRight;
}
public Rect getBottomRect() {
return bottom;
}
public Rect getHRect() {
return horizontal;
}
public int getHealth() {
return health;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setHealth(int health) {
this.health = health;
}
public void shot() {
currIcon = iconShot;
Bullet b = new Bullet((float) (x + iconShot.getWidth()),
(float) (y + ((26.31 * iconShot.getHeight()) / 100)),
Helper.convertPx_Dpi(10, context), 2);
bullets.add(b);
}
public void _shot() {
currIcon = icon;
}
public List<Bullet> getBullets() {
return bullets;
}
public void jump() {
if (!isJumping && canJump) {
isJumping = true;
isFalling = false;
speedY = JumpSpeed;
}
}
public void increaseHealth(int x){
health += x;
if(health > 100){
health = 100;
}
}
public void degreeseHealth(int a) {
health -= a;
}
}
Your app can resume while obscured by the lock screen. If you want to tell the difference between "resume is hidden by a lock screen" and "resume is actually displayed" you can check your window focus.
See Making Android Games that Play Nice for more details.
A different way to get a similar "wait until actually displayed" is to wait for the first Activity.onUserInteraction after a resume before restarting your game.

how to fill adapter to viewpage fully without going aside?

I am trying to change viewpage rotation 90 to get vertical swapping. but my adapter going aside. i am unable fix it. help me to fit layout correctly.
Here is my view pager
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_alignParentTop="true"
android:layout_width="800dp"
android:layout_height="480dp"
android:background="#a07fe0">
</android.support.v4.view.ViewPager>
Here is my layout of adapter
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ff0000"
android:layout_centerInParent="true"
android:orientation="horizontal"
android:rotation="270">
<ImageView
android:id="#+id/screen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="start"
android:src="#drawable/makescr1"/>
</LinearLayout>
Use This class.
public class VerticalPager extends ViewGroup {
public static final String TAG = "VerticalPager";
private static final int INVALID_SCREEN = -1;
public static final int SPEC_UNDEFINED = -1;
private static final int TOP = 0;
private static final int BOTTOM = 1;
/**
* The velocity at which a fling gesture will cause us to snap to the next screen
*/
private static final int SNAP_VELOCITY = 1000;
private int pageHeight;
private int measuredHeight;
private boolean mFirstLayout = true;
private int mCurrentPage;
private int mNextPage = INVALID_SCREEN;
private Scroller mScroller;
private VelocityTracker mVelocityTracker;
private int mTouchSlop;
private int mMaximumVelocity;
private float mLastMotionY;
private float mLastMotionX;
private final static int TOUCH_STATE_REST = 0;
private final static int TOUCH_STATE_SCROLLING = 1;
private int mTouchState = TOUCH_STATE_REST;
private boolean mAllowLongPress;
private Set<OnScrollListener> mListeners = new HashSet<OnScrollListener>();
VerticalPageChange mpageChangeListener;
/**
* Used to inflate the Workspace from XML.
*
* #param context The application's context.
* #param attrs The attribtues set containing the Workspace's customization values.
*/
public VerticalPager(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public VerticalPager(Context context, AttributeSet attrs,
VerticalPageChange mpageChangeListener) {
this(context, attrs, 0);
this.mpageChangeListener=mpageChangeListener;
}
/**
* Used to inflate the Workspace from XML.
*
* #param context The application's context.
* #param attrs The attribtues set containing the Workspace's customization values.
* #param defStyle Unused.
*/
public VerticalPager(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
//TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.com_deezapps_widget_HorizontalPager);
//pageHeightSpec = a.getDimensionPixelSize(R.styleable.com_deezapps_widget_HorizontalPager_pageWidth, SPEC_UNDEFINED);
//a.recycle();
init(context);
}
/**
* Initializes various states for this workspace.
*/
private void init(Context context) {
mScroller = new Scroller(getContext(), new DecelerateInterpolator());
mCurrentPage = 0;
final ViewConfiguration configuration = ViewConfiguration.get(getContext());
mTouchSlop = configuration.getScaledTouchSlop();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
}
/**
* Returns the index of the currently displayed page.
*
* #return The index of the currently displayed page.
*/
int getCurrentPage() {
return mCurrentPage;
}
/**
* Sets the current page.
*
* #param currentPage
*/
public void setCurrentPage(int currentPage) {
mCurrentPage = Math.max(0, Math.min(currentPage, getChildCount()));
scrollTo(getScrollYForPage(mCurrentPage), 0);
invalidate();
}
public int getPageHeight() {
return pageHeight;
}
// public void setPageHeight(int pageHeight) {
// this.pageHeightSpec = pageHeight;
// }
/**
* Gets the value that getScrollX() should return if the specified page is the current page (and no other scrolling is occurring).
* Use this to pass a value to scrollTo(), for example.
* #param whichPage
* #return
*/
private int getScrollYForPage(int whichPage) {
int height = 0;
for(int i = 0; i < whichPage; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != View.GONE) {
height += child.getHeight();
}
}
return height - pageHeightPadding();
}
#Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
} else if (mNextPage != INVALID_SCREEN) {
mCurrentPage = mNextPage;
mNextPage = INVALID_SCREEN;
clearChildrenCache();
}
}
#Override
protected void dispatchDraw(Canvas canvas) {
// ViewGroup.dispatchDraw() supports many features we don't need:
// clip to padding, layout animation, animation listener, disappearing
// children, etc. The following implementation attempts to fast-track
// the drawing dispatch by drawing only what we know needs to be drawn.
final long drawingTime = getDrawingTime();
// todo be smarter about which children need drawing
final int count = getChildCount();
for (int i = 0; i < count; i++) {
drawChild(canvas, getChildAt(i), drawingTime);
}
for (OnScrollListener mListener : mListeners) {
int adjustedScrollY = getScrollY() + pageHeightPadding();
mListener.onScroll(adjustedScrollY);
if (adjustedScrollY % pageHeight == 0) {
mListener.onViewScrollFinished(adjustedScrollY / pageHeight);
}
}
}
int pageHeightPadding() {
return ((getMeasuredHeight() - pageHeight) / 2);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
pageHeight = getMeasuredHeight();
final int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(pageHeight, MeasureSpec.UNSPECIFIED));
}
if (mFirstLayout) {
scrollTo(getScrollYForPage(mCurrentPage), 0);
mFirstLayout = false;
}
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
measuredHeight = 0;
final int count = getChildCount();
int height;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != View.GONE) {
if(i == 0) {
child.getHeight();
child.layout(0, measuredHeight, right - left, measuredHeight + (int)(pageHeight*.96));
measuredHeight += (pageHeight*.96);
} else {
height = pageHeight * (int)Math.ceil((double)child.getMeasuredHeight()/(double)pageHeight);
height = Math.max(pageHeight, height);
child.layout(0, measuredHeight, right - left, measuredHeight + height);
measuredHeight += height;
}
}
}
}
#Override
public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
int screen = indexOfChild(child);
if (screen != mCurrentPage || !mScroller.isFinished()) {
return true;
}
return false;
}
#Override
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
int focusableScreen;
try
{
if (mNextPage != INVALID_SCREEN) {
focusableScreen = mNextPage;
} else {
focusableScreen = mCurrentPage;
}
getChildAt(focusableScreen).requestFocus(direction, previouslyFocusedRect);
}
catch(Exception e)
{
e.printStackTrace();
}
return false;
}
#Override
public boolean dispatchUnhandledMove(View focused, int direction) {
if (direction == View.FOCUS_LEFT) {
if (getCurrentPage() > 0) {
snapToPage(getCurrentPage() - 1);
return true;
}
} else if (direction == View.FOCUS_RIGHT) {
if (getCurrentPage() < getChildCount() - 1) {
snapToPage(getCurrentPage() + 1);
return true;
}
}
return super.dispatchUnhandledMove(focused, direction);
}
#Override
public void addFocusables(ArrayList<View> views, int direction) {
getChildAt(mCurrentPage).addFocusables(views, direction);
if (direction == View.FOCUS_LEFT) {
if (mCurrentPage > 0) {
getChildAt(mCurrentPage - 1).addFocusables(views, direction);
}
} else if (direction == View.FOCUS_RIGHT){
if (mCurrentPage < getChildCount() - 1) {
getChildAt(mCurrentPage + 1).addFocusables(views, direction);
}
}
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//Log.d(TAG, "onInterceptTouchEvent::action=" + ev.getAction());
/*
* This method JUST determines whether we want to intercept the motion.
* If we return true, onTouchEvent will be called and we do the actual
* scrolling there.
*/
/*
* Shortcut the most recurring case: the user is in the dragging
* state and he is moving his finger. We want to intercept this
* motion.
*/
final int action = ev.getAction();
if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST)) {
//Log.d(TAG, "onInterceptTouchEvent::shortcut=true");
return true;
}
final float y = ev.getY();
final float x = ev.getX();
switch (action) {
case MotionEvent.ACTION_MOVE:
/*
* mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
* whether the user has moved far enough from his original down touch.
*/
if (mTouchState == TOUCH_STATE_REST) {
checkStartScroll(x, y);
}
break;
case MotionEvent.ACTION_DOWN:
// Remember location of down touch
mLastMotionX = x;
mLastMotionY = y;
mAllowLongPress = true;
/*
* If being flinged and user touches the screen, initiate drag;
* otherwise don't. mScroller.isFinished should be false when
* being flinged.
*/
mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
// Release the drag
clearChildrenCache();
mTouchState = TOUCH_STATE_REST;
break;
}
/*
* The only time we want to intercept motion events is if we are in the
* drag mode.
*/
return mTouchState != TOUCH_STATE_REST;
}
private void checkStartScroll(float x, float y) {
/*
* Locally do absolute value. mLastMotionX is set to the y value
* of the down event.
*/
final int xDiff = (int) Math.abs(x - mLastMotionX);
final int yDiff = (int) Math.abs(y - mLastMotionY);
boolean xMoved = xDiff > mTouchSlop;
boolean yMoved = yDiff > mTouchSlop;
if (xMoved || yMoved) {
if (yMoved) {
// Scroll if the user moved far enough along the X axis
mTouchState = TOUCH_STATE_SCROLLING;
enableChildrenCache();
}
// Either way, cancel any pending longpress
if (mAllowLongPress) {
mAllowLongPress = false;
// Try canceling the long press. It could also have been scheduled
// by a distant descendant, so use the mAllowLongPress flag to block
// everything
final View currentScreen = getChildAt(mCurrentPage);
currentScreen.cancelLongPress();
}
}
}
void enableChildrenCache() {
setChildrenDrawingCacheEnabled(true);
setChildrenDrawnWithCacheEnabled(true);
}
void clearChildrenCache() {
setChildrenDrawnWithCacheEnabled(false);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(ev);
final int action = ev.getAction();
final float x = ev.getX();
final float y = ev.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
/*
* If being flinged and user touches, stop the fling. isFinished
* will be false if being flinged.
*/
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
// Remember where the motion event started
mLastMotionY = y;
break;
case MotionEvent.ACTION_MOVE:
if (mTouchState == TOUCH_STATE_REST) {
checkStartScroll(y, x);
} else if (mTouchState == TOUCH_STATE_SCROLLING) {
// Scroll to follow the motion event
int deltaY = (int) (mLastMotionY - y);
mLastMotionY = y;
// Apply friction to scrolling past boundaries.
final int count = getChildCount();
if (getScrollY() < 0 || getScrollY() + pageHeight > getChildAt(count - 1).getBottom()) {
deltaY /= 2;
}
scrollBy(0, deltaY);
}
break;
case MotionEvent.ACTION_UP:
if (mTouchState == TOUCH_STATE_SCROLLING) {
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
int velocityY = (int) velocityTracker.getYVelocity();
final int count = getChildCount();
// check scrolling past first or last page?
if(getScrollY() < 0) {
snapToPage(0);
} else if(getScrollY() > measuredHeight - pageHeight) {
snapToPage(count - 1, BOTTOM);
} else {
for(int i = 0; i < count; i++) {
final View child = getChildAt(i);
if(child.getTop() < getScrollY() &&
child.getBottom() > getScrollY() + pageHeight) {
// we're inside a page, fling that bitch
mNextPage = i;
mScroller.fling(getScrollX(), getScrollY(), 0, -velocityY, 0, 0, child.getTop(), child.getBottom() - getHeight());
invalidate();
break;
} else if(child.getBottom() > getScrollY() && child.getBottom() < getScrollY() + getHeight()) {
// stuck in between pages, oh snap!
if(velocityY < -SNAP_VELOCITY) {
snapToPage(i + 1);
} else if(velocityY > SNAP_VELOCITY) {
snapToPage(i, BOTTOM);
} else if(getScrollY() + pageHeight/2 > child.getBottom()) {
snapToPage(i + 1);
} else {
snapToPage(i, BOTTOM);
}
break;
}
}
}
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}
mTouchState = TOUCH_STATE_REST;
break;
case MotionEvent.ACTION_CANCEL:
mTouchState = TOUCH_STATE_REST;
}
return true;
}
private void snapToPage(final int whichPage, final int where) {
enableChildrenCache();
boolean changingPages = whichPage != mCurrentPage;
mNextPage = whichPage;
View focusedChild = getFocusedChild();
if (focusedChild != null && changingPages && focusedChild == getChildAt(mCurrentPage)) {
focusedChild.clearFocus();
}
final int delta;
if(getChildAt(whichPage).getHeight() <= pageHeight || where == TOP) {
delta = getChildAt(whichPage).getTop() - getScrollY();
} else {
delta = getChildAt(whichPage).getBottom() - pageHeight - getScrollY();
}
mScroller.startScroll(0, getScrollY(), 0, delta, 400);
invalidate();
mpageChangeListener.onPageChange(whichPage);
}
public void snapToPage(final int whichPage) {
snapToPage(whichPage, TOP);
// mpageChangeListener.onPageChange(whichPage);
}
#Override
protected Parcelable onSaveInstanceState() {
final SavedState state = new SavedState(super.onSaveInstanceState());
state.currentScreen = mCurrentPage;
return state;
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
if (savedState.currentScreen != INVALID_SCREEN) {
mCurrentPage = savedState.currentScreen;
}
}
public void scrollUp() {
if (mNextPage == INVALID_SCREEN && mCurrentPage > 0 && mScroller.isFinished()) {
snapToPage(mCurrentPage - 1);
}
}
public void scrollDown() {
if (mNextPage == INVALID_SCREEN && mCurrentPage < getChildCount() - 1 && mScroller.isFinished()) {
snapToPage(mCurrentPage + 1);
}
}
public int getScreenForView(View v) {
int result = -1;
if (v != null) {
ViewParent vp = v.getParent();
int count = getChildCount();
for (int i = 0; i < count; i++) {
if (vp == getChildAt(i)) {
return i;
}
}
}
return result;
}
/**
* #return True is long presses are still allowed for the current touch
*/
public boolean allowLongPress() {
return mAllowLongPress;
}
public static class SavedState extends BaseSavedState {
int currentScreen = -1;
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentScreen = in.readInt();
}
#Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(currentScreen);
}
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
public void addOnScrollListener(OnScrollListener listener) {
mListeners.add(listener);
}
public void removeOnScrollListener(OnScrollListener listener) {
mListeners.remove(listener);
}
/**
* Implement to receive events on scroll position and page snaps.
*/
public static interface OnScrollListener {
/**
* Receives the current scroll X value. This value will be adjusted to assume the left edge of the first
* page has a scroll position of 0. Note that values less than 0 and greater than the right edge of the
* last page are possible due to touch events scrolling beyond the edges.
* #param scrollX Scroll X value
*/
void onScroll(int scrollX);
/**
* Invoked when scrolling is finished (settled on a page, centered).
* #param currentPage The current page
*/
void onViewScrollFinished(int currentPage);
}
public interface VerticalPageChange
{
public void onPageChange(int position);
}
}
i have add page dynamically. inside getView() of BaseAdapter.
final VerticalPager verticalPage = new VerticalPager(Act_ItemView.this, null, mVerticalPagechangeListener);
// setDotIndicatorView(p.arr_images.size());
for (int i = 0; i < p.arr_images.size(); i++)
{
final String image_url = p.arr_images.get(i).image_method;
PhotoView imageView = new PhotoView(Act_ItemView.this);
imageView.setLayoutParams(new ViewGroup.LayoutParams(width, height));
imageView.setAllowParentInterceptOnEdge(true);
// imageView.setScaleType(ScaleType.CENTER_CROP);
imageLoader1.displayImage(image_url, imageView, options1, animateFirstListener1);
verticalPage.setHorizontalScrollBarEnabled(false);
verticalPage.addView(imageView);
verticalPage.setTag(i);
}
linearLayoutMain.addView(verticalPage);
here is listner implemented
VerticalPager.VerticalPageChange mVerticalPagechangeListener = new VerticalPager.VerticalPageChange()
{
#Override
public void onPageChange(int position)
{
try
{
int pagePosition1 = viewPager.getCurrentItem();
setindicator(position);
array_index[pagePosition1] = position;
} catch (Exception e)
{
e.printStackTrace();
}
}
};

Categories

Resources