I want to implement a rotating banner. What control is best suitable for such UI?
here is what it needs to do:
So essentially when you land on first activity the first index is shown. When you do swipe it should show next or previous image depending if the swipe is to the left or to the right. This should iterate in the infinite loop.
Thank you in advance
In case anybody wanted the solution, here is the code:
public class CustomBanner extends RelativeLayout {
//================================================================================
//==== declaration.
protected List<Banner> _items = new ArrayList<Banner>();
protected GestureDetector gestureDetector;
protected View.OnTouchListener gestureListener;
protected ImageView _banner = null;
protected String TAG = "CustomBanner";
//================================================================================
//================================================================================
//==== properties
/**
* This property pulls the banners from the state manager. If the banners are not there they will be pulled from the database.
* */
protected List<Banner> getBanners()
{
// get your banners however way you get them
return this._items;
}
//================================================================================
//================================================================================
//==== constructors
public CustomBanner(Context context, AttributeSet attributes)
{
super(context, attributes);
this.Init(context, attributes);
}
//================================================================================
//================================================================================
//==== protected methods
protected void Init(Context context, AttributeSet attributes)
{
//---- inflate our layout
LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater.inflate(R.drawable.controls_custombanner, this);
this._banner = (ImageView)findViewById(R.id.imgBanner);
// swipe detection on the image
this.gestureDetector = new GestureDetector(new MyGestureDetector());
this.gestureListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
return true;
}
return false;
}
};
// leave this, it needs to be here in order to redirect the swipe correctly to touch gesture direction
this._banner.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// leave blank, click is redirected to gesture
}
});
this._banner.setOnTouchListener(gestureListener);
// set banner image
this.setBanner(this.getCurrentIndexByWndId());
}
protected int getCurrentIndexByWndId() {
// add your logic here
// you need to access your state to get the last saved id
}
/**
* this function does nothing but set the banner image by the position from the array of banners.
* */
protected void setBanner(int position)
{
_banner.setImageResource(this.getBanners().get(position).ResourceId);
}
/**
* this function tests the validity of the index in the banners array and resets it to 0 if its not valid.
* */
protected int checkValidIndex(int currentIndex){
if (currentIndex > this.getBanners().size()-1)
currentIndex = 0;
return currentIndex;
}
protected void processBannerClick(Banner clickedBanner){
try
{
// here do your logic for the click
}
catch (Exception ex)
{
Log.e(App.Current.getErrorTag(), ex.getMessage());
}
}
//================================================================================
//================================================================================
//==== helper classes
/**
* this is a helper class to detect the gesture or swipe. It uses the onFling() to test whether it was a right or left swipe.
* It increments the position of and sets the appropriate next image on the banner.
* */
protected class MyGestureDetector extends SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.i(TAG, "BANNER: onFling() happened");
int currentIndex = 0;
try {
currentIndex = FromState.getCurrentAdRotatorPosition();
if(isScrollingLeft(e1, e2)) {
// left swipe
if (currentIndex > 0)
currentIndex --;
else currentIndex = getBanners().size()-1;
}
else {
// right swipe
if (currentIndex < getBanners().size()-1)
currentIndex ++;
else currentIndex = 0;
}
} catch (Exception e) {
// do nothing
}
FromState..setCurrentAdRotatorPosition(currentIndex);
setBanner(FromState.getCurrentAdRotatorPosition());
return false;
}
@Override
public boolean onSingleTapUp(MotionEvent ev)
{
Log.i(TAG, "BANNER: onSingleTapUp() happened");
processBannerClick(getBanners().get(FromState.getCurrentAdRotatorPosition()));
return false;
}
/** check if left swipe happened */
private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2){
return e2.getX() > e1.getX();
}
}
//================================================================================
}