Android:View Pager horizontal scroll is not smooth - android

I am using view pager indicator and i have sucessfully implemented it but My problem is that my swipe is very slow.Any help regarding this will be appreciated.
My indicator activity:
public class ViewPagerIndicatorActivity extends FragmentActivity {
static PagerAdapter mPagerAdapter;
static ViewPager mViewPager;
static ViewPagerIndicator mIndicator;
static int position,position1;
static String PositionTitle;
static String addposition;
ProgressDialog dialog;
public Context _context=this;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create our custom adapter to supply pages to the viewpager.
try{
mPagerAdapter = new PagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setAdapter(mPagerAdapter);
// Start at a custom position
RelativeLayout firsthead=(RelativeLayout)findViewById(R.id.firsthead);
firsthead.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent ii=new Intent(getApplicationContext(),WebviewNew.class);
startActivity(ii);
}
});
mViewPager.setCurrentItem(0);
mIndicator = (ViewPagerIndicator)findViewById(R.id.indicator);
mViewPager.setOnPageChangeListener(mIndicator);
}catch (Exception e) {
// TODO: handle exception
System.out.println(e);
}
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
mViewPager.setAdapter(null);
super.onDestroy();
}
class OnIndicatorClickListener implements ViewPagerIndicator.OnClickListener{
#Override
public void onCurrentClicked(View v) {
Toast.makeText(ViewPagerIndicatorActivity.this, "Hello", Toast.LENGTH_SHORT).show();
}
#Override
public void onNextClicked(View v) {
mViewPager.setCurrentItem(Math.min(mPagerAdapter.getCount() - 1, mIndicator.getCurrentPosition() + 1));
}
#Override
public void onPreviousClicked(View v) {
mViewPager.setCurrentItem(Math.max(0, mIndicator.getCurrentPosition() - 1));
}
}
class PagerAdapter extends FragmentPagerAdapter implements ViewPagerIndicator.PageInfoProvider{
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
Fragment f = new Fragment();
if(pos==0)
{
f=LayoutOne.newInstance(_context);
}
if(pos==1)
{
f=LayoutTwo.newInstance(_context);
}
if(pos==2)
{
f=Layoutthree.newInstance(_context);
}
if(pos==3)
{
f=Layoutfour.newInstance(_context);
}
return f;
}
#Override
public int getCount() {
return list2.length;
}
#Override
public String getTitle(int pos){
PositionTitle=list2[pos];
return PositionTitle;
}
}
public static class ItemFragment extends ListFragment{
String[] l1;
static ItemFragment newInstance1(String[] date) {
ItemFragment f = new ItemFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putStringArray("date", date);
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
this.l1=list2;
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.date_fragment, container, false);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
public static final String[] list2 = new String[]{"Catagories","Latest","Most Downloaded","Top Rated"};
private class StartTaskP extends AsyncTask<String, String, String>
{
#Override
protected void onPreExecute()
{
// TODO Auto-generated method stub
super.onPreExecute();
dialog = ProgressDialog.show(ViewPagerIndicatorActivity.this, "Please wait", "Loading...");
}
#Override
protected String doInBackground(String... params)
{
String hello = null;
try
{} catch (Exception e)
{
e.printStackTrace();
}
return hello;
}
#Override
protected void onPostExecute(String result)
{
// TODO Auto-generated method stub
super.onPostExecute(result);
try{
mIndicator.init(0, mPagerAdapter.getCount(), mPagerAdapter);
Resources res = getResources();
System.out.println("test11");
Drawable prev = res.getDrawable(R.drawable.indicator_prev_arrow);
Drawable next = res.getDrawable(R.drawable.indicator_next_arrow);
mIndicator.setFocusedTextColor(new int[]{78, 103, 0});
mIndicator.setUnfocusedTextColor(new int[]{255,255,255});
//mIndicator.setFocusedTextColor(R.drawable.navigationtextcurrent);
// Set images for previous and next arrows.
mIndicator.setArrows(prev, next);
mIndicator.setOnClickListener(new OnIndicatorClickListener());
}
catch (Exception e) {
// TODO: handle exception
System.out.println(e);
}
dialog.dismiss();
}
}
and my ViewPagerIndicator:
public class ViewPagerIndicator extends RelativeLayout implements OnPageChangeListener {
private static final int PADDING = 10;
int i=0;
TextView mPrevious;
TextView mCurrent;
TextView mNext;
static int mCurItem;
int mRestoreCurItem = -1;
Intent ii= new Intent();
Context mContext;
static int PresentPosition1;
static String textCarrier;
LinearLayout mPreviousGroup;
LinearLayout mNextGroup;
int mArrowPadding;
int mSize;
ImageView mCurrentIndicator;
ImageView mPrevArrow;
ImageView mNextArrow;
static PageInfoProvider mPageInfoProvider;
int[] mFocusedTextColor;
int[] mUnfocusedTextColor;
OnClickListener mOnClickHandler;
public interface PageInfoProvider{
String getTitle(int pos);
}
public interface OnClickListener{
void onNextClicked(View v);
void onPreviousClicked(View v);
void onCurrentClicked(View v);
}
public void setOnClickListener(OnClickListener handler){
this.mOnClickHandler = handler;
mPreviousGroup.setOnClickListener(new OnPreviousClickedListener());
mCurrent.setOnClickListener(new OnCurrentClickedListener());
mNextGroup.setOnClickListener(new OnNextClickedListener());
}
public int getCurrentPosition(){
return mCurItem;
}
public void setPageInfoProvider(PageInfoProvider pageInfoProvider){
this.mPageInfoProvider = pageInfoProvider;
}
public void setFocusedTextColor(int[] col){
System.arraycopy(col, 0, mFocusedTextColor, 0, 3);
updateColor(0);
}
public void setUnfocusedTextColor(int[] col){
System.arraycopy(col, 0, mUnfocusedTextColor, 0, 3);
mNext.setTextColor(Color.argb(160, col[0], col[1], col[2]));
mPrevious.setTextColor(Color.argb(160, col[0], col[1], col[2]));
updateColor(0);
}
#Override
protected Parcelable onSaveInstanceState() {
Parcelable state = super.onSaveInstanceState();
Bundle b = new Bundle();
b.putInt("current", this.mCurItem);
b.putParcelable("viewstate", state);
return b;
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(((Bundle)state).getParcelable("viewstate"));
mCurItem = ((Bundle)state).getInt("current", mCurItem);
this.setText(mCurItem - 1);
this.updateArrows(mCurItem);
this.invalidate();
}
/**
* Initialization
*
* #param startPos The initially selected element in the ViewPager
* #param size Total amount of elements in the ViewPager
* #param pageInfoProvider Interface that returns page titles
*/
public void init(int startPos, int size, PageInfoProvider pageInfoProvider){
setPageInfoProvider(pageInfoProvider);
this.mSize = size;
setText(startPos - 1);
mCurItem = startPos;
}
public ViewPagerIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
addContent();
}
public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyle){
super(context, attrs, defStyle);
addContent();
}
public ViewPagerIndicator(Context context) {
super(context);
addContent();
}
/**
* Add drawables for arrows
*
* #param prev Left pointing arrow
* #param next Right pointing arrow
*/
public void setArrows(Drawable prev, Drawable next){
this.mPrevArrow = new ImageView(getContext());
//this.mPrevArrow.setImageDrawable(prev);
this.mPrevArrow.setVisibility(View.INVISIBLE);
this.mNextArrow = new ImageView(getContext());
//this.mNextArrow.setImageDrawable(next);
LinearLayout.LayoutParams arrowLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//arrowLayoutParams.gravity = Gravity.CENTER;
mPreviousGroup.removeAllViews();
mPreviousGroup.addView(mPrevArrow, arrowLayoutParams);
mPreviousGroup.addView(mPrevious, arrowLayoutParams);
mPrevious.setPadding(PADDING, 0, 0, 0);
mNext.setPadding(0, 0, PADDING, 0);
mArrowPadding = PADDING + prev.getIntrinsicWidth();
mNextGroup.addView(mNextArrow, arrowLayoutParams);
updateArrows(mCurItem);
}
/**
* Create all views, build the layout
*/
private void addContent(){
mFocusedTextColor = new int[]{244, 240, 211};
mUnfocusedTextColor = new int[]{160,131,21};
// Text views
// set font
mPrevious = new TextView(getContext());
mCurrent = new TextView(getContext());
mNext = new TextView(getContext());
RelativeLayout.LayoutParams previousParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
previousParams.addRule(RelativeLayout.ALIGN_LEFT);
previousParams.leftMargin=-28;
previousParams.topMargin=10;
RelativeLayout.LayoutParams currentParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
currentParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
currentParams.topMargin=10;
RelativeLayout.LayoutParams nextParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
nextParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
nextParams.rightMargin=-40;
nextParams.topMargin=10;
// Groups holding text and arrows
mPreviousGroup = new LinearLayout(getContext());
mPreviousGroup.setOrientation(LinearLayout.HORIZONTAL);
mNextGroup = new LinearLayout(getContext());
mNextGroup.setOrientation(LinearLayout.HORIZONTAL);
mPreviousGroup.addView(mPrevious, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mNextGroup.addView(mNext, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
addView(mPreviousGroup, previousParams);
addView(mCurrent, currentParams);
addView(mNextGroup, nextParams);
mPrevious.setSingleLine();
mCurrent.setSingleLine();
mNext.setSingleLine();
mPrevious.setText("previous");
mCurrent.setText("current");
mNext.setText("next");
try{
Typeface tf=Typeface.createFromAsset(getContext().getAssets(), "fonts/trebuc.otf");
mPrevious.setTypeface(tf);
mCurrent.setTypeface(tf);
mNext.setTypeface(tf);
}catch (Exception e) {
// TODO: handle exception
System.out.println(e);
}
mPrevious.setClickable(false);
mNext.setClickable(false);
mCurrent.setClickable(true);
mPreviousGroup.setClickable(true);
mNextGroup.setClickable(true);
// Set colors
mNext.setTextColor(Color.argb(255, mUnfocusedTextColor[0], mUnfocusedTextColor[1], mUnfocusedTextColor[2]));
mPrevious.setTextColor(Color.argb(255, mUnfocusedTextColor[0], mUnfocusedTextColor[1], mUnfocusedTextColor[2]));
updateColor(0);
}
#Override
public void onPageScrollStateChanged(int state) {
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
positionOffsetPixels = adjustOffset(positionOffsetPixels);
position = updatePosition(position, positionOffsetPixels);
setText(position - 1);
/*System.out.println("PageScrolled:"+(position-1));
System.out.println("PageScrollednew:"+PresentPosition);
*/updateColor(positionOffsetPixels-1);
updateArrows(position);
//updatePositions(positionOffsetPixels);
updatePositions(position);
mCurItem = position;
Bundle ii=new Bundle();
//ii.putExtra("mcurItem", mCurItem);
ii.putInt("key", mCurItem);
}
void updatePositions(int positionOffsetPixels){
int textWidth = mCurrent.getWidth() - mCurrent.getPaddingLeft() - mCurrent.getPaddingRight();
int maxOffset = this.getWidth() / 2 - textWidth / 2 - mArrowPadding;
if(positionOffsetPixels > 0){
maxOffset %= this.getPaddingLeft();
int offset = Math.min(positionOffsetPixels, maxOffset);
mCurrent.setPadding(0, 0, 2 * offset, 0);
}else{
maxOffset -= this.getPaddingRight();
int offset = Math.max(positionOffsetPixels, -maxOffset);
mCurrent.setPadding(-2 * offset, 0, 0, 0);
}
}
void updateArrows(int position){
if(mPrevArrow != null){
mPrevArrow.setVisibility(position == 0 ? View.INVISIBLE : View.VISIBLE);
mNextArrow.setVisibility(position == mSize - 1 ? View.INVISIBLE : View.VISIBLE);
}
}
int updatePosition(int givenPosition, int offset){
int pos;
if(offset < 0){
pos = givenPosition + 1;
}else{
pos = givenPosition;
}
return pos;
}
/**
* Fade "currently showing" color depending on it's position
*
* #param offset
*/
void updateColor(int offset){
offset = Math.abs(offset);
// Initial condition: offset is always 0, this.getWidth is also 0! 0/0 = NaN
int width = this.getWidth();
float fraction = width == 0 ? 0 : offset / ((float)width / 4.0f);
fraction = Math.min(1, fraction);
int r = (int)(mUnfocusedTextColor[0] * fraction + mFocusedTextColor[0] * (1 - fraction));
int g = (int)(mUnfocusedTextColor[1] * fraction + mFocusedTextColor[1] * (1 - fraction));
int b = (int)(mUnfocusedTextColor[2] * fraction + mFocusedTextColor[2] * (1 - fraction));
mCurrent.setTextColor(Color.argb(255, r, g, b));
}
/**
* Update text depending on it's position
*
* #param prevPos
*/
void setText(int prevPos){
PresentPosition1=prevPos;
if(prevPos < 0){
mPrevious.setText("");
}else{
mPrevious.setText(mPageInfoProvider.getTitle(prevPos));
}
mCurrent.setText(mPageInfoProvider.getTitle(prevPos + 1));
PresentPosition1=prevPos;
//System.out.println("present text"+mPageInfoProvider.getTitle(prevPos + 1));
if(prevPos + 2 == this.mSize){
mNext.setText("");
}else{
mNext.setText(mPageInfoProvider.getTitle(prevPos + 2));
}
}
// Original:
// 244, 245, 0, 1, 2
// New:
// -2, -1, 0, 1, 2
int adjustOffset(int positionOffsetPixels){
// Move offset half width
positionOffsetPixels += this.getWidth() / 2;
// Clamp to width
positionOffsetPixels %= this.getWidth();
// Center around zero
positionOffsetPixels -= this.getWidth() / 2;
return positionOffsetPixels;
}
#Override
public void onPageSelected(int position) {
// Reset padding when the page is finally selected (May not be necessary)
mCurrent.setPadding(0, 0, 0, 0);
}
class OnPreviousClickedListener implements android.view.View.OnClickListener{
#Override
public void onClick(View v) {
if(mOnClickHandler != null){
mOnClickHandler.onPreviousClicked(ViewPagerIndicator.this);
}
}
}
class OnCurrentClickedListener implements android.view.View.OnClickListener{
#Override
public void onClick(View v) {
if(mOnClickHandler != null){
mOnClickHandler.onCurrentClicked(ViewPagerIndicator.this);
}
}
}
class OnNextClickedListener implements android.view.View.OnClickListener{
#Override
public void onClick(View v) {
if(mOnClickHandler != null){
mOnClickHandler.onNextClicked(ViewPagerIndicator.this);
}
}
}
}

Related

How to play live streaming in RecyclerView using libVLC?

I am developing app to monitor IP camera using my mobile. Below is my MainActivity. I am using libVLC which uses surfaceview to show the video.
public class MainActivity extends AppCompatActivity {
Button prevButton, nextButton;
private int totalPages, currentPage;
RecyclerView recyclerView;
VideoAdapter videoAdapter;
static List<String> cameraList;
Paginator p;
#SuppressLint("AuthLeak")
private String[] vidUrlList = {
"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4",
"https://archive.org/download/ksnn_compilation_master_the_internet/ksnn_compilation_master_the_internet_512kb.mp4",
"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4",
"rtsp://184.72.239.149/vod/mp4:BigBuckBunny_175k.mov",
"http://live.hkstv.hk.lxdns.com/live/hks/playlist.m3u8",
"rtsp://admin:admin#192.0.0.0:200/12"
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
prevButton = (Button) findViewById(R.id.prev_btn);
nextButton = (Button) findViewById(R.id.next_btn);
prevButton.setEnabled(false);
cameraList = new ArrayList<>(Arrays.asList(vidUrlList));
p = new Paginator();
totalPages = Paginator.TOTAL_NUM_ITEMS / Paginator.ITEMS_PER_PAGE;
currentPage = 0;
videoAdapter = new VideoAdapter(this, cameraList);
final RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(3),
true));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(new VideoAdapter(MainActivity.this, p.generatePage(currentPage)));
nextButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
currentPage += 1;
recyclerView.setAdapter(new VideoAdapter(MainActivity.this, p.generatePage(currentPage)));
toggleButtons();
}
});
prevButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
currentPage -= 1;
recyclerView.setAdapter(new VideoAdapter(MainActivity.this, p.generatePage(currentPage)));
toggleButtons();
}
});
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
}
public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
private int spanCount;
private int spacing;
private boolean includeEdge;
public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
this.spanCount = spanCount;
this.spacing = spacing;
this.includeEdge = includeEdge;
}
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view);
int column = position % spanCount;
if (includeEdge) {
outRect.left = spacing - column * spacing / spanCount;
outRect.right = (column + 1) * spacing / spanCount;
if (position < spanCount) {
outRect.top = spacing;
}
outRect.bottom = spacing;
} else {
outRect.left = column * spacing / spanCount;
outRect.right = spacing - (column + 1) * spacing / spanCount;
if (position >= spanCount) {
outRect.top = spacing;
}
}
}
}
private int dpToPx(int dp) {
Resources r = getResources();
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dp, r.getDisplayMetrics()));
}
private void toggleButtons() {
if (currentPage == totalPages) {
nextButton.setEnabled(false);
prevButton.setEnabled(true);
} else if (currentPage == 0) {
prevButton.setEnabled(false);
nextButton.setEnabled(true);
} else if (currentPage >= 1 && currentPage <= totalPages) {
nextButton.setEnabled(true);
prevButton.setEnabled(true);
}
}
public static List<String> getModifyList() {
return cameraList;
}}
I used RecylerView and CardView with Paginator option for dispaying 4 cards in each page. Since i have n number of cameras to maintain i used Paginator. Below is my Paginator Class.
public class Paginator {
static List<String> arrNewList = MainActivity.getModifyList();
public static final int TOTAL_NUM_ITEMS = arrNewList.size();
public static final int ITEMS_PER_PAGE = 4;
public static final int ITEMS_REMAINING = TOTAL_NUM_ITEMS % ITEMS_PER_PAGE;
public static final int LAST_PAGE = TOTAL_NUM_ITEMS / ITEMS_PER_PAGE;
public ArrayList<String> generatePage(int currentPage) {
int startItem = currentPage * ITEMS_PER_PAGE;
int numOfData = ITEMS_PER_PAGE;
ArrayList<String> pageData = new ArrayList<>();
if (currentPage == LAST_PAGE && ITEMS_REMAINING > 0) {
for (int i = startItem; i < startItem + ITEMS_REMAINING; i++) {
pageData.add(arrNewList.get(i));
}
} else {
for (int i = startItem; i < startItem + numOfData; i++) {
pageData.add(arrNewList.get(i));
}
}
return pageData;
}}
Here i am trying to set adapter in which video is playing only at the last postion of each page. I dont know how to solve this. I am proving my adapter code below. Here i called SurfaceHolder.Callback and IVideoPlayer interfaces. Do come up with the solution.
public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.ViewHolder>
implements SurfaceHolder.Callback, IVideoPlayer {
Context mContext;
List<String> cameraList;
SurfaceHolder surfaceHolder;
private int mVideoWidth;
private int mVideoHeight;
private final static int VideoSizeChanged = -1;
//private SurfaceView mSurfaceView;
private LibVLC libvlc;
EventHandler mEventHandler;
public VideoAdapter(Context mContext, List<String> cameraList) {
this.mContext = mContext;
this.cameraList = cameraList;
}
#Override
public VideoAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.camera_adapter, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(VideoAdapter.ViewHolder holder, int position) {
surfaceHolder.addCallback(this);
String urlList = cameraList.get(position);
Log.e("List1", "-->" + urlList);
createPlayer(urlList);
}
#Override
public int getItemCount() {
return cameraList.size();
}
public NativeCrashHandler.OnNativeCrashListener nativecrashListener = new NativeCrashHandler.OnNativeCrashListener() {
#Override
public void onNativeCrash() {
Log.e("vlcdebug", "nativecrash");
}
};
#Override
public void surfaceCreated(SurfaceHolder holder) {
Log.e("mylog", "surfaceCreated");
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
try {
if (libvlc != null) {
Log.e("mylog", "libvlc != null");
libvlc.attachSurface(surfaceHolder.getSurface(), this);
} else {
Log.e("mylog", "libvlc == null");
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e("mylog", "surfaceDestroyed");
}
public class ViewHolder extends RecyclerView.ViewHolder {
private SurfaceView mSurfaceView;
public ViewHolder(View itemView) {
super(itemView);
mSurfaceView = itemView.findViewById(R.id.player_surface);
surfaceHolder = mSurfaceView.getHolder();
}
}
private void createPlayer(String vidUrlList) {
//releasePlayer();
try {
libvlc = new LibVLC();
mEventHandler = libvlc.getEventHandler();
libvlc.init(mContext);
libvlc.setHardwareAcceleration(LibVLC.HW_ACCELERATION_FULL);
libvlc.setSubtitlesEncoding("");
libvlc.setAout(LibVLC.AOUT_OPENSLES);
libvlc.setTimeStretching(true);
libvlc.setVerboseMode(true);
libvlc.setNetworkCaching(1000);
NativeCrashHandler.getInstance().setOnNativeCrashListener(
nativecrashListener);
if (LibVlcUtil.isGingerbreadOrLater())
libvlc.setVout(LibVLC.VOUT_ANDROID_WINDOW);
else
libvlc.setVout(LibVLC.VOUT_ANDROID_SURFACE);
LibVLC.restartInstance(mContext);
mEventHandler.addHandler(mHandler);
surfaceHolder.setKeepScreenOn(true);
MediaList list = libvlc.getMediaList();
list.clear();
list.add(new Media(libvlc, LibVLC.PathToURI(vidUrlList)), false);
//list.add(new Media(libvlc, LibVLC.PathToURI(media)), false);
//list.add(new Media(libvlc, LibVLC.PathToURI(media)), false);
libvlc.playIndex(0);
} catch (Exception e) {
Toast.makeText(mContext, "Error creating player!", Toast.LENGTH_SHORT).show();
}
}
private void releasePlayer() {
try {
EventHandler.getInstance().removeHandler(mHandler);
//libvlc.stop();
libvlc.detachSurface();
surfaceHolder = null;
libvlc.closeAout();
libvlc.destroy();
libvlc = null;
mVideoWidth = 0;
mVideoHeight = 0;
} catch (Exception e) {
e.printStackTrace();
}
}
private Handler mHandler = new MyHandler(this);
#Override
public void setSurfaceLayout(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den) {
Message msg = Message.obtain(mHandler, VideoSizeChanged, width,
height);
msg.sendToTarget();
}
#Override
public int configureSurface(Surface surface, int width, int height, int hal) {
Log.d("", "configureSurface: width = " + width + ", height = "
+ height);
if (LibVlcUtil.isICSOrLater() || surface == null)
return -1;
if (width * height == 0)
return 0;
if (hal != 0)
surfaceHolder.setFormat(hal);
surfaceHolder.setFixedSize(width, height);
return 1;
}
#Override
public void eventHardwareAccelerationError() {
//releasePlayer();
Toast.makeText(mContext, "Error with hardware acceleration",
Toast.LENGTH_SHORT).show();
}
#Override
public void setSurfaceSize(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den) {
}
#SuppressLint("HandlerLeak")
private class MyHandler extends Handler {
private WeakReference<VideoAdapter> mOwner;
MyHandler(VideoAdapter owner) {
mOwner = new WeakReference<>(owner);
}
#Override
public void handleMessage(Message msg) {
try {
VideoAdapter player = mOwner.get();
Log.e("mylog", "handleMessage " + msg.toString());
// Libvlc events
Bundle b = msg.getData();
Log.e("mylog", "handleMessage " + msg.getData());
switch (b.getInt("event")) {
case EventHandler.MediaPlayerEndReached:
Log.e("mylog", "MediaPlayerEndReached");
player.releasePlayer();
break;
case EventHandler.MediaPlayerPlaying:
Log.e("mylog", "MediaPlayerPlaying");
break;
case EventHandler.MediaPlayerPaused:
Log.e("mylog", "MediaPlayerPaused");
break;
case EventHandler.MediaPlayerStopped:
Log.e("mylog", "MediaPlayerStopped");
break;
case EventHandler.MediaPlayerPositionChanged:
Log.i("vlc", "MediaPlayerPositionChanged");
//VideoAdapter.this.notify();
break;
case EventHandler.MediaPlayerEncounteredError:
break;
default:
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}}
The problem is that you get your LibVLC instance using class's member varible like this
// kotlin
private libvlc: LibVLC? = null
...
override fun onBindViewHolder(...) {
libvlc = LibVLC()
...
}
which means each time you call onBindViewHolder, get a new instance of LibVLC and assign it to member variable libvlc, libvlc points to a new address of your new LibVLC instance, and the older one can not be refered again.
In other words, four list items in your RecyclerView share a same LibVLC instance, when you attach view/surface, the later visible views let your libvlc detach views from the older ones the reattach to the newest one, so only the last view can play normally.

Android: Animation works in KitKat and LolliPop but not on other API versions

I have to build animation like This.
Sorry I don't have too much reputation to upload image. you can find gif file from the above link.
I have done all this and it works fine on KitKat and LollyPop only but not on the other API version. I am using this library. Can any one please figure out the actual problem
Here is my code. Thanks in advance
public abstract class AbstractSlideExpandableListAdapter extends WrapperListAdapterImpl
{
private View lastOpnUpperView = null;
ArrayList<View> upperViewsList = new ArrayList<View>();
ArrayList<View> lowerViewsList = new ArrayList<View>();
ArrayList<View> circleViewsList = new ArrayList<View>();
private View lastOpen = null;
private int lastOpenPosition = -1;
private int lastOpenItemIndex = 0;
private int animationDuration = 800;
private BitSet openItems = new BitSet();
private final SparseIntArray viewHeights = new SparseIntArray(10);
private ViewGroup parent;
public AbstractSlideExpandableListAdapter(ListAdapter wrapped)
{
super(wrapped);
lastOpenPosition = 0;
openItems.set(lastOpenPosition, true);
}
private OnItemExpandCollapseListener expandCollapseListener;
public void setItemExpandCollapseListener(OnItemExpandCollapseListener listener)
{
expandCollapseListener = listener;
}
public void removeItemExpandCollapseListener()
{
expandCollapseListener = null;
}
public interface OnItemExpandCollapseListener
{
public void onExpand(View itemView, int position);
public void onCollapse(View itemView, int position);
}
private void notifiyExpandCollapseListener(int type, View view, int position)
{
if (expandCollapseListener != null)
{
if (type == ExpandCollapseAnimation.EXPAND)
{
expandCollapseListener.onExpand(view, position);
}
else if (type == ExpandCollapseAnimation.COLLAPSE)
{
expandCollapseListener.onCollapse(view, position);
}
}
}
#Override
public View getView(int position, View view, ViewGroup viewGroup)
{
this.parent = viewGroup;
view = wrapped.getView(position, view, viewGroup);
enableFor(view, position);
return view;
}
public abstract View getExpandToggleButton(View parent);
public abstract View getExpandableView(View parent);
// upperView to expand animation for sequeeze
public abstract View getUpperView(View upperView);
// Lower view to expand and collapse
public abstract View getLowerView(View upperView);
// Get the circle view to hide and show
public abstract View getCircleView(View circleView);
/**
* Gets the duration of the collapse animation in ms. Default is 330ms. Override this method to change the default.
*
* #return the duration of the anim in ms
*/
public int getAnimationDuration()
{
return animationDuration;
}
/**
* Set's the Animation duration for the Expandable animation
*
* #param duration
* The duration as an integer in MS (duration > 0)
* #exception IllegalArgumentException
* if parameter is less than zero
*/
public void setAnimationDuration(int duration)
{
if (duration < 0)
{
throw new IllegalArgumentException("Duration is less than zero");
}
animationDuration = duration;
}
/**
* Check's if any position is currently Expanded To collapse the open item #see collapseLastOpen
*
* #return boolean True if there is currently an item expanded, otherwise false
*/
public boolean isAnyItemExpanded()
{
return (lastOpenPosition != -1) ? true : false;
}
public void enableFor(View parent, int position)
{
View more = getExpandToggleButton(parent);
View itemToolbar = getExpandableView(parent);
View upperView = getUpperView(parent);
View circleView = getCircleView(parent);
View lowerView = getLowerView(parent);
itemToolbar.measure(parent.getWidth(), parent.getHeight());
upperViewsList.add(upperView);
circleViewsList.add(circleView);
lowerViewsList.add(lowerView);
if (position == 0)
{
// lastopenUpperViewTemporary = upperView;
lastOpnUpperView = upperView;
upperView.setVisibility(View.GONE);
lowerView.setVisibility(View.GONE);
}
enableFor(more, upperView, itemToolbar, position);
itemToolbar.requestLayout();
}
private void animateListExpand(final View button, final View target, final int position)
{
target.setAnimation(null);
int type;
if (target.getVisibility() == View.VISIBLE)
{
type = ExpandCollapseAnimation.COLLAPSE;
}
else
{
type = ExpandCollapseAnimation.EXPAND;
}
// remember the state
if (type == ExpandCollapseAnimation.EXPAND)
{
openItems.set(position, true);
}
else
{
openItems.set(position, false);
}
// check if we need to collapse a different view
if (type == ExpandCollapseAnimation.EXPAND)
{
if (lastOpenPosition != -1 && lastOpenPosition != position)
{
if (lastOpen != null)
{
animateWithUpperView(lastOpen, ExpandCollapseAnimation.COLLAPSE, position);
// animateView(lastOpen, ExpandCollapseAnimation.COLLAPSE);
notifiyExpandCollapseListener(ExpandCollapseAnimation.COLLAPSE, lastOpen, lastOpenPosition);
}
openItems.set(lastOpenPosition, false);
}
lastOpen = target;
lastOpenPosition = position;
}
else if (lastOpenPosition == position)
{
lastOpenPosition = -1;
}
// animateView(target, type);
// Expand the view which was collapse
Animation anim = new ExpandCollapseAnimation(target, type);
anim.setDuration(getAnimationDuration());
target.startAnimation(anim);
this.notifiyExpandCollapseListener(type, target, position);
// }
}
private void enableFor(final View button, final View upperView, final View target, final int position)
{
// lastopenUpperViewTemporary = upperView;
if (target == lastOpen && position != lastOpenPosition)
{
// lastOpen is recycled, so its reference is false
lastOpen = null;
}
if (position == lastOpenPosition)
{
// re reference to the last view
// so when can animate it when collapsed
// lastOpen = target;
lastOpen = target;
lastOpnUpperView = upperView;
}
int height = viewHeights.get(position, -1);
if (height == -1)
{
viewHeights.put(position, target.getMeasuredHeight());
updateExpandable(target, position);
}
else
{
updateExpandable(target, position);
}
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(final View view)
{
System.out.println("Position: " + position);
if (lastOpenPosition == position)
{
return;
}
System.out.println("Upper View: " + upperView);
Animation anim = new ExpandCollapseUpperViewAnimation(upperViewsList.get(position), ExpandCollapseUpperViewAnimation.COLLAPSE);
anim.setDuration(800);
anim.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
circleViewsList.get(position).setVisibility(View.GONE);
}
#Override
public void onAnimationRepeat(Animation animation)
{
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation)
{
// TODO Auto-generated method stub
// upperViewsList.get(position).setVisibility(View.VISIBLE);
animateListExpand(button, target, position);
}
});
upperViewsList.get(position).startAnimation(anim);
// Lower animation
Animation lowerAnim = new ExpandCollapseUpperViewAnimation(lowerViewsList.get(position), ExpandCollapseUpperViewAnimation.COLLAPSE);
lowerAnim.setDuration(800);
lowerViewsList.get(position).startAnimation(lowerAnim);
}
});
}
private void updateExpandable(View target, int position)
{
final LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) target.getLayoutParams();
if (openItems.get(position))
{
target.setVisibility(View.VISIBLE);
params.bottomMargin = 0;
}
else
{
target.setVisibility(View.GONE);
params.bottomMargin = 0 - viewHeights.get(position);
}
}
/**
* Performs either COLLAPSE or EXPAND animation on the target view
*
* #param target
* the view to animate
* #param type
* the animation type, either ExpandCollapseAnimation.COLLAPSE or ExpandCollapseAnimation.EXPAND
*/
private void animateView(final View target, final int type)
{
Animation anim = new ExpandCollapseAnimation(target, type);
anim.setDuration(getAnimationDuration());
anim.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
}
#Override
public void onAnimationRepeat(Animation animation)
{
}
#Override
public void onAnimationEnd(Animation animation)
{
System.out.println("Animation End");
if (type == ExpandCollapseAnimation.EXPAND)
{
if (parent instanceof ListView)
{
ListView listView = (ListView) parent;
int movement = target.getBottom();
Rect r = new Rect();
boolean visible = target.getGlobalVisibleRect(r);
Rect r2 = new Rect();
listView.getGlobalVisibleRect(r2);
if (!visible)
{
listView.smoothScrollBy(movement, getAnimationDuration());
}
else
{
if (r2.bottom == r.bottom)
{
listView.smoothScrollBy(movement, getAnimationDuration());
}
}
}
}
}
});
target.startAnimation(anim);
}
private void animateWithUpperView(final View target, final int type, final int position)
{
Animation anim = new ExpandCollapseAnimation(target, type);
anim.setDuration(getAnimationDuration());
anim.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
}
#Override
public void onAnimationRepeat(Animation animation)
{
}
#Override
public void onAnimationEnd(Animation animation)
{
// upperViewsList.get(lastOpenItemForUpperView).setVisibility(View.VISIBLE);
// lastOpenItemForUpperView = position;
Animation expandItemAniamtion = new ExpandCollapseLowerViewAnimation(upperViewsList.get(lastOpenItemIndex), ExpandCollapseUpperViewAnimation.EXPAND);
expandItemAniamtion.setDuration(800);
expandItemAniamtion.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
}
#Override
public void onAnimationRepeat(Animation animation)
{
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation)
{
circleViewsList.get(lastOpenItemIndex).setVisibility(View.VISIBLE);
lastOpenItemIndex = position;
}
});
// Lower view animation
Animation lowerAnim = new ExpandCollapseLowerViewAnimation(lowerViewsList.get(lastOpenItemIndex), ExpandCollapseUpperViewAnimation.EXPAND);
lowerAnim.setDuration(800);
upperViewsList.get(lastOpenItemIndex).startAnimation(expandItemAniamtion);
lowerViewsList.get(lastOpenItemIndex).startAnimation(lowerAnim);
}
});
target.startAnimation(anim);
}
/**
* Closes the current open item. If it is current visible it will be closed with an animation.
*
* #return true if an item was closed, false otherwise
*/
public boolean collapseLastOpen()
{
if (isAnyItemExpanded())
{
// if visible animate it out
if (lastOpen != null)
{
animateView(lastOpen, ExpandCollapseAnimation.COLLAPSE);
}
openItems.set(lastOpenPosition, false);
lastOpenPosition = -1;
return true;
}
return false;
}
public Parcelable onSaveInstanceState(Parcelable parcelable)
{
SavedState ss = new SavedState(parcelable);
ss.lastOpenPosition = this.lastOpenPosition;
ss.openItems = this.openItems;
return ss;
}
public void onRestoreInstanceState(SavedState state)
{
if (state != null)
{
this.lastOpenPosition = state.lastOpenPosition;
this.openItems = state.openItems;
}
}
/**
* Utility methods to read and write a bitset from and to a Parcel
*/
private static BitSet readBitSet(Parcel src)
{
BitSet set = new BitSet();
if (src == null)
{
return set;
}
int cardinality = src.readInt();
for (int i = 0; i < cardinality; i++)
{
set.set(src.readInt());
}
return set;
}
private static void writeBitSet(Parcel dest, BitSet set)
{
int nextSetBit = -1;
if (dest == null || set == null)
{
return; // at least dont crash
}
dest.writeInt(set.cardinality());
while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1)
{
dest.writeInt(nextSetBit);
}
}
/**
* The actual state class
*/
static class SavedState extends View.BaseSavedState
{
public BitSet openItems = null;
public int lastOpenPosition = -1;
SavedState(Parcelable superState)
{
super(superState);
}
private SavedState(Parcel in)
{
super(in);
lastOpenPosition = in.readInt();
openItems = readBitSet(in);
}
#Override
public void writeToParcel(Parcel out, int flags)
{
super.writeToParcel(out, flags);
out.writeInt(lastOpenPosition);
writeBitSet(out, openItems);
}
// required field that makes Parcelables from a Parcel
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 static Animation ExpandOrCollapseView(final View v, final boolean expand)
{
try
{
Method m = v.getClass().getDeclaredMethod("onMeasure", int.class, int.class);
m.setAccessible(true);
m.invoke(v, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(((View) v.getParent()).getMeasuredWidth(), MeasureSpec.AT_MOST));
}
catch (Exception e)
{
e.printStackTrace();
}
final int initialHeight = v.getMeasuredHeight();
if (expand)
{
v.getLayoutParams().height = 0;
}
else
{
v.getLayoutParams().height = initialHeight;
}
v.setVisibility(View.VISIBLE);
Animation a = new Animation()
{
#Override
protected void applyTransformation(float interpolatedTime, Transformation t)
{
int newHeight = 0;
if (expand)
{
newHeight = (int) (initialHeight * interpolatedTime);
}
else
{
newHeight = (int) (initialHeight * (1 - interpolatedTime));
}
v.getLayoutParams().height = newHeight;
v.requestLayout();
if (interpolatedTime == 1 && !expand)
v.setVisibility(View.GONE);
}
#Override
public boolean willChangeBounds()
{
return true;
}
};
a.setDuration(1000);
return a;
}}
Luckily I have found the solution. On pre-kitkat the upperView on list item which was gone does not forcelly animate but on kitkat and so on it forcelly animate from gone to visible.
So as the solution we must give a layer of view between of list item and upper view (Which we have to animate).
In this way it will work like charm.

Give Arc Effect on Buttons for circular menu in android?

Hiii
i have to create circular menu after R & D i got the following output which is display in image 1 but i want to give effect like image 2 i will put it my code here so you can check it
My current Output image 1 in this button and text display horizontally i want to convert this to arc effect both button and text like below image 2
i want to make this buttons like this image
MainActivity.java
public class MainActivity extends MenuActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override public void createButtons() {
for(int i = 0 ; i < 3 ; i++) {
RotativeButton button = new RotativeButton(this);
if(i==0)
{
button.setBackgroundResource(R.drawable.green);
//button.setBackgroundColor(Color.GREEN);
button.setText("Insurance Green");
button.setPosition(i);
button.setLabel("OPTION "+(i+1));
button.setLayoutParams(new LinearLayout.LayoutParams(100, 100));
}
if(i==1)
{
button.setBackgroundResource(R.drawable.red);
//button.setBackgroundColor(Color.RED);
button.setText("Insurance Red");
button.setPosition(i);
button.setLabel("OPTION "+(i+1));
button.setLayoutParams(new LinearLayout.LayoutParams(100, 100));
}
if(i==2)
{
button.setBackgroundResource(R.drawable.yellow);
//button.setBackgroundColor(Color.YELLOW);
button.setText("Insurance Yellow");
button.setPosition(i);
button.setLabel("OPTION "+(i+1));
button.setLayoutParams(new LinearLayout.LayoutParams(100, 100));
}
Intent intent = new Intent(this, DetailActivity.class);
intent.putExtra("id", String.valueOf(i+1));
button.setIntent(intent);
mButtonList.add(button);
}
}
}
MenuActivity.java
public abstract class MenuActivity extends Activity {
protected List<RotativeButton> mButtonList = new ArrayList<RotativeButton>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.common_view);
// RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.mainView);
LinearLayout mainLayout=(LinearLayout)findViewById(R.id.mainView);
getLayoutInflater().inflate(R.layout.menu, mainLayout, true);
final RotativeMenuView customView = (RotativeMenuView) findViewById(R.id.rotativeMenuView);
final Button okBtn = (Button) customView.findViewById(R.id.okBtn);
customView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener()
{
public void onGlobalLayout()
{
if(okBtn.getVisibility()==View.VISIBLE)
{
customView.addButtons(mButtonList);
customView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
createButtons();
}
protected abstract void createButtons();
}
RotativeButton.java
public class RotativeButton extends Button {
private int position;
private Intent intent;
private String label;
public RotativeButton(Context context) {
super(context);
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public Intent getIntent() {
return intent;
}
public void setIntent(Intent intent) {
this.intent = intent;
}
}
RotativeMenuView.java
public class RotativeMenuView extends RelativeLayout
{
private List<RotativeButton> _buttonList;
private HashMap<Integer, Point > _pointForPosition = new HashMap<Integer, Point>();
private HashMap<Integer, RectF > _rectForPosition = new HashMap<Integer, RectF>();
private TextView titleTv;
public RotativeMenuView(Context context) {
super(context);
}
public RotativeMenuView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public RotativeMenuView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
public void addButtons(List<RotativeButton> buttonList) {
final Button okBtn = (Button) findViewById(R.id.okBtn);
titleTv = (TextView) findViewById(R.id.labelTv);
okBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
RotativeButton activeButton = getActiveButton();
Intent i = activeButton.getIntent();
getContext().startActivity(i);
}
});
_buttonList = buttonList;
int numberOfButtons = buttonList.size();
final double angle = 360 / numberOfButtons;
int okWidth = okBtn.getMeasuredWidth();
int okHeight = okBtn.getMeasuredHeight();
Log.e("OK_WIDTH", String.valueOf(okWidth));
Log.e("OK_HEIGHT", String.valueOf(okHeight));
int okLeft = okBtn.getLeft();
int okTop = okBtn.getTop();
Log.e("okLeft", String.valueOf(okLeft));
Log.e("okTop", String.valueOf(okTop));
int distance = okWidth;
Log.e("distance", String.valueOf(distance));
final int[] point = new int[2];
okBtn.getLocationInWindow(point);
for (int i = 0; i < numberOfButtons; i++) {
RotativeButton rotativeButton = buttonList.get(i);
int position = rotativeButton.getPosition();
int buttonHeight = rotativeButton.getBackground()
.getIntrinsicHeight();
int buttonWidth = rotativeButton.getBackground()
.getIntrinsicWidth();
int diffHeight = (okHeight / 2) - (buttonHeight / 2);
int diffWidth = (okWidth / 2) - (buttonWidth / 2);
float newAngle = (float) angle * position;
Point nextPoint = nextPosition(okTop + diffHeight, okLeft
+ diffWidth, newAngle, distance);
int newLeft = nextPoint.x;
int newTop = nextPoint.y;
final RectF okRect = new RectF(point[0] - newLeft
- okBtn.getWidth() + diffWidth, point[1] - newTop
- okBtn.getHeight() + diffHeight, (point[0] - newLeft)
+ okBtn.getWidth() + diffWidth, (point[1] - newTop)
+ okBtn.getHeight() + diffHeight);
rotativeButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
final RotativeButton clickedButton = (RotativeButton) v;
int position = clickedButton.getPosition();
if (position == 0) {
return;
}
int total = _buttonList.size();
final int clickedPosition = total - position;
double angle = 360 / total;
titleTv.setVisibility(INVISIBLE);
for (int i = 0; i < total; i++) {
final RotativeButton currentButton = _buttonList.get(i);
position = currentButton.getPosition();
RectF rectF = _rectForPosition.get(position);
float startAngle = (float) angle * position;
Path aPath = new Path();
aPath.addArc(rectF, startAngle, (float) angle
* clickedPosition);
Animation anim = new PathAnimation(aPath);
anim.setDuration(500);
anim.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
currentButton.setClickable(false);
okBtn.setClickable(false);
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationEnd(Animation animation) {
currentButton.setClickable(true);
okBtn.setClickable(true);
updatePosition(currentButton, clickedPosition);
currentButton.clearAnimation();
}
});
anim.setFillBefore(true);
currentButton.startAnimation(anim);
}
}
});
LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.topMargin = newTop;
params.leftMargin = newLeft;
addView(rotativeButton, params);
if (position == 0) {
applyLabel(rotativeButton.getLabel());
}
_pointForPosition.put(position, nextPoint);
_rectForPosition.put(position, okRect);
}
}
public void updatePosition(final RotativeButton currentButton, int diffPosition){
int total = _buttonList.size();
int currentPosition = currentButton.getPosition();
int newPosition = currentPosition + diffPosition;
if(newPosition >= total ){
newPosition -= total;
}
currentButton.setPosition(newPosition);
Point pointForPosition = _pointForPosition.get(newPosition);
int newLeft = pointForPosition.x;
int newTop = pointForPosition.y;
Log.d("CustomView", "Button: "+ currentButton.getPosition()+ "("+currentButton.getLabel()+") , New Left:" +newLeft+" top: "+ newTop);
currentButton.layout(newLeft, newTop,
newLeft + currentButton.getMeasuredWidth(), newTop + currentButton.getMeasuredHeight());
Log.d("CustomView", "Moving from:" +currentPosition+" to: "+currentButton.getPosition() + "code: " +currentButton.getLabel());
if (newPosition == 0) {
applyLabel(currentButton.getLabel());
}
}
protected void applyLabel( String label) {
titleTv.setText(label.toUpperCase());
titleTv.setVisibility(VISIBLE);
}
private Point nextPosition(int okTop, int okLeft, double angle, int distance) {
int x = okLeft + (int) (distance*Math.cos(Math.toRadians(angle)));
int y = okTop + (int) (distance*Math.sin(Math.toRadians(angle)));
Log.e("X", String.valueOf(x));
Log.e("Y", String.valueOf(y));
Point p = new Point();
p.set(x, y);
return p;
}
private RotativeButton getActiveButton()
{
for (RotativeButton aButton : _buttonList)
{
int position = aButton.getPosition();
if(position == 0)
{
return aButton;
}
}
return null;
}
}
PathAnimation.java
public class PathAnimation extends Animation {
private PathMeasure measure;
private float[] pos = new float[2];
public PathAnimation(Path path) {
measure = new PathMeasure(path, false);
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t){
measure.getPosTan(measure.getLength() * interpolatedTime, pos,null);
t.getMatrix().setTranslate(pos[0], pos[1]);
}
}

Encounter Range-seek-bar runtime error in android

I have used this tutorial https://code.google.com/p/range-seek-bar/#Example_usage_as_Integer_range?.
Encountered runtime error of my activity stopped. Would like to seek help from you. I attempted to correct the following compile errors as listed below.
RangeSeekBar<Integer> seekBar = new RangeSeekBar<Integer>(20, 75, context);
Context cannot be resolved to a variable
I tried adding changing context to this.
Log.i(TAG, "User selected new range values: MIN=" + minValue + ", MAX=" + maxValue);
TAG cannot be resolved to a variable.
I tried adding "protected static final String TAG = null;" to main activity.
ViewGroup layout = (ViewGroup) findViewById(<your-layout-id>)
Does the layout id refer to my main_activity.xml in my layout?
Really grateful for your feedback.
MainActivity.Java
package com.example.rangeseekbargooglecode;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.ViewGroup;
import com.example.rangeseekbargooglecode.RangeSeekBar.OnRangeSeekBarChangeListener;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String TAG = null;
// create RangeSeekBar as Integer range between 20 and 75
RangeSeekBar<Integer> seekBar = new RangeSeekBar<Integer>(20, 75, this);
seekBar.setOnRangeSeekBarChangeListener(new OnRangeSeekBarChangeListener<Integer>() {
#Override
public void onRangeSeekBarValuesChanged(RangeSeekBar<?> bar, Integer minValue, Integer maxValue) {
// handle changed range values
Log.i(TAG, "User selected new range values: MIN=" + minValue + ", MAX=" + maxValue);
}
});
// add RangeSeekBar to pre-defined layout
ViewGroup layout = (ViewGroup) findViewById(R.layout.activity_main);
layout.addView(seekBar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
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" >
<SeekBar
android:id="#+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginTop="109dp" />
</RelativeLayout>
Edited Code to allow TextView to display range.
public class MainActivity extends Activity {
private TextView textview;
protected static final String TAG = "com.example.gto_doubleseekbar";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview = (TextView) findViewById(R.id.textView1);
// create RangeSeekBar as Integer range between 20 and 75
RangeSeekBar<Integer> seekBar = new RangeSeekBar<Integer>(20, 75, this);
seekBar.setOnRangeSeekBarChangeListener(new OnRangeSeekBarChangeListener<Integer>() {
#Override
public void onRangeSeekBarValuesChanged(RangeSeekBar<?> bar, Integer minValue, Integer maxValue) {
// handle changed range values
String powerranger = "User selected new range values: MIN=" + minValue + ", MAX=" + maxValue;
Log.i(TAG, powerranger);
textview.setText(powerranger);
}
});
// add RangeSeekBar to pre-defined layout
LayoutInflater inflater = (LayoutInflater)getApplicationContext().getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.activity_main,null);
layout.addView(seekBar);
setContentView(layout);
}
RangeSeekBar seekBar = new RangeSeekBar(20, 75, context); 1. Context cannot be resolved to a variable
this must work:
RangeSeekBar seekBar = new RangeSeekBar(20, 75, this);
Log.i(TAG, "User selected new range values: MIN=" + minValue + ", MAX=" + maxValue); 2. TAG cannot be resolved to a variable. I tried adding "protected static final String TAG = null;" to main activity.
Don't set it to null. Usually you use the app or component name, e.g.
protected static final String TAG = "MyApp";
ViewGroup layout = (ViewGroup) findViewById() 3. Does the layout id refer to my main_activity.xml in my layout?
Use this:
LayoutInflater inflater = (LayoutInflater)getApplicationContext().getSystemService (Context.LAYOUT_INFLATER_SERVICE);
ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.activity_main,null);
layout.addView(seekBar);
setContentView(layout);
Try to implement custom RangeSeekBar.
xml file:
<com.doondoz.utility.common_function.RangeSeekBar
android:id="#+id/seekBarPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:left_index="0"
android:layout_weight="0.90" />
java file:
RangeSeekBar.java
public class RangeSeekBar extends View {
private static final int DEFAULT_HEIGHT = 70;
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_TICK_COUNT = 100;
private Thumb leftThumb, rightThumb;
private Thumb pressedThumb = null;
private SeekBar seekBar;
private Paint thumbPaint;
private OnRangeSeekBarChangerListener mListener;
private int mTickCount;
private int mLeftIndex = 0;
private int mRightIndex;
private int mThumbColor;
private int mThumbNormalRadius;
private int mThumbPressedRadius;
public RangeSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
public RangeSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public RangeSeekBar(Context context) {
super(context);
}
#SuppressWarnings("deprecation")
private void init(Context context, AttributeSet attrs) {
Resources resources = getResources();
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RangeSeekBar);
try {
mTickCount = typedArray.getInteger(R.styleable.RangeSeekBar_tick_count, DEFAULT_TICK_COUNT);
mRightIndex = mTickCount - 1;
mThumbColor = typedArray.getColor(R.styleable.RangeSeekBar_thumb_color, getResources().getColor(R.color.thumb_default));
mThumbNormalRadius = typedArray.getDimensionPixelSize(R.styleable.RangeSeekBar_thumb_normal_radius, 12);
mThumbPressedRadius = typedArray.getDimensionPixelSize(R.styleable.RangeSeekBar_thumb_pressed_radius, 16);
mLeftIndex = typedArray.getInteger(R.styleable.RangeSeekBar_left_index, 0);
mRightIndex = typedArray.getInteger(R.styleable.RangeSeekBar_right_index, mRightIndex);
if (mLeftIndex < 0)
throw new IllegalArgumentException("Left index must be >= 0");
if (mRightIndex > mTickCount)
throw new IllegalArgumentException("Right index must be <= tick count");
} finally {
typedArray.recycle();
}
setUp();
}
private void setUp() {
thumbPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
thumbPaint.setStyle(Paint.Style.FILL);
thumbPaint.setColor(mThumbColor);
leftThumb = new Thumb(0, 0, thumbPaint, mThumbNormalRadius, mThumbPressedRadius);
rightThumb = new Thumb(0, 0, thumbPaint, mThumbNormalRadius, mThumbPressedRadius);
seekBar = new SeekBar(0, 0, 0, Color.BLACK, 1, mThumbColor, 3);
seekBar.setTickNumb(mTickCount);
}
public void setOnRangeBarChangeListener(OnRangeSeekBarChangerListener onRangeBarChangeListener) {
mListener = onRangeBarChangeListener;
}
/**
* Set number of ticks
*
* #param tickCount Default is 100
*/
public void setTickCount(int tickCount) {
mTickCount = tickCount;
seekBar.setTickNumb(mTickCount);
invalidate();
}
/**
* Set thumb's color
*
* #param thumbColor Default is orange
*/
public void setThumbColor(int thumbColor) {
mThumbColor = thumbColor;
thumbPaint.setColor(mThumbColor);
invalidate();
}
/**
* Set thumb's normal radius
*
* #param thumbRadius Default is 6dp
*/
public void setThumbNormalRadius(float thumbRadius) {
mThumbNormalRadius = (int) (thumbRadius*getResources().getDisplayMetrics().density);
leftThumb.radius = mThumbNormalRadius;
rightThumb.radius = mThumbNormalRadius;
invalidate();
}
/**
* Set thumb's pressed radius
*
* #param thumbPressedRadius Default is 8dp
*/
public void setThumbPressedRadius(float thumbPressedRadius) {
mThumbPressedRadius = (int) (thumbPressedRadius*getResources().getDisplayMetrics().density);
leftThumb.pressedRadius = mThumbPressedRadius;
rightThumb.pressedRadius = mThumbPressedRadius;
invalidate();
}
/**
* Set index for the Left Thumb
*
* #param leftIndex Default is 0
*/
public void setLeftIndex(int leftIndex) {
if (leftIndex < 0) {
throw new IllegalArgumentException("Left index must be >= 0");
}
mLeftIndex = leftIndex;
leftThumb.setIndex(seekBar, mLeftIndex);
invalidate();
}
/**
* Set index for the Right thumb
*
* #param rightIndex Default is 99
*/
public void setRightIndex(int rightIndex) {
if (rightIndex > mTickCount) {
throw new IllegalArgumentException("Left index must be <= tick count");
}
mRightIndex = rightIndex;
leftThumb.setIndex(seekBar, mRightIndex);
invalidate();
}
/**
* Get left index
*
* #return int
*/
public int getLeftIndex() {
return mLeftIndex;
}
/**
* Get right index
*
* #return int
*/
public int getRightIndex() {
return mRightIndex;
}
/**
* Get number of tick
*
* #return int
*/
public int getTickCount() {
return mTickCount;
}
#Override
protected synchronized void onDraw(Canvas canvas) {
seekBar.draw(canvas, leftThumb, rightThumb);
leftThumb.draw(canvas);
rightThumb.draw(canvas);
if (pressedThumb != null && pressedThumb.isAnimating) {
invalidate();
}
}
#Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height, width;
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(heightSize, DEFAULT_HEIGHT);
} else {
height = DEFAULT_HEIGHT;
}
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
width = Math.min(widthSize, DEFAULT_WIDTH);
} else {
width = DEFAULT_WIDTH;
}
setMeasuredDimension(width, height);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
pressedThumb = checkThumbPressed(eventX, eventY);
if (pressedThumb == null) {
return super.onTouchEvent(event);
}
pressedThumb.setPressed(true);
invalidate();
setPressed(true);
return true;
case MotionEvent.ACTION_MOVE:
onActionMove(eventX);
return true;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (pressedThumb == null) {
return super.onTouchEvent(event);
}
onActionUp();
break;
}
return super.onTouchEvent(event);
}
private void onActionUp() {
pressedThumb.onActionUp(seekBar);
invalidate();
}
private void onActionMove(float eventX) {
if (eventX >= seekBar.leftX && eventX <= seekBar.rightX) {
pressedThumb.x = eventX;
invalidate();
if (leftThumb.x > rightThumb.x) {
final Thumb temp = leftThumb;
leftThumb = rightThumb;
rightThumb = temp;
}
int leftIndex = seekBar.getNearestTick(leftThumb);
int rightIndex = seekBar.getNearestTick(rightThumb);
if (mLeftIndex != leftIndex || mRightIndex != rightIndex) {
mLeftIndex = leftIndex;
mRightIndex = rightIndex;
if (mListener != null) {
mListener.onIndexChange(this, mLeftIndex, mRightIndex);
}
}
}
}
private Thumb checkThumbPressed(float eventX, float eventY) {
Thumb result = null;
boolean isLeftThumbPressed = leftThumb.isInTargetZone(eventX, eventY);
boolean isRightThumbPressed = rightThumb.isInTargetZone(eventX, eventY);
if (isLeftThumbPressed && isRightThumbPressed) {
result = (eventX / getWidth() >= 0.5f) ? leftThumb : rightThumb;
} else if (isLeftThumbPressed) {
result = leftThumb;
} else if (isRightThumbPressed) {
result = rightThumb;
}
return result;
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
leftThumb.x = (getPaddingLeft() + 20 + leftThumb.normalRadius / 2);
leftThumb.y = (h + getPaddingTop() + getPaddingBottom()) / 2;
rightThumb.y = leftThumb.y;
rightThumb.x = (w - getPaddingRight() - 20 - rightThumb.normalRadius / 2);
seekBar.leftX = leftThumb.x;
seekBar.rightX = rightThumb.x;
seekBar.y = leftThumb.y;
leftThumb.setIndex(seekBar, mLeftIndex);
rightThumb.setIndex(seekBar, mRightIndex);
}
#Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
SavedState state = new SavedState(super.onSaveInstanceState());
state.tickCount = mTickCount;
state.leftIndex = mLeftIndex;
state.rightIndex = mRightIndex;
state.thumbColor = mThumbColor;
state.thumbNormalRadius = mThumbNormalRadius;
state.thumbPressedRadius = mThumbPressedRadius;
bundle.putParcelable(SavedState.STATE,state);
return bundle;
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
SavedState savedState = bundle.getParcelable(SavedState.STATE);
mTickCount = savedState.tickCount;
mThumbColor = savedState.thumbColor;
mThumbNormalRadius = savedState.thumbNormalRadius;
mThumbPressedRadius = savedState.thumbPressedRadius;
mLeftIndex = savedState.leftIndex;
mRightIndex = savedState.rightIndex;
super.onRestoreInstanceState(savedState.getSuperState());
return;
}
super.onRestoreInstanceState(SavedState.EMPTY_STATE);
}
public interface OnRangeSeekBarChangerListener {
void onIndexChange(RangeSeekBar rangeBar, int leftIndex, int rightIndex);
}
static class SavedState extends BaseSavedState {
static final String STATE = "RangeSeekBar.STATE";
int tickCount;
int leftIndex;
int rightIndex;
int thumbColor;
int thumbNormalRadius;
int thumbPressedRadius;
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
}
#Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
}
public static final Creator<SavedState> CREATOR =
new Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}

How to do 3DTransition on a MapView?

In my app I have a list of events and their descriptions, now I want to show the event location on a MapView. So I used a 3dTransition as described in Android api demo (ApiDemo > Views > Animation > 3D Transition). The 3D Transition is working fine, but the problem is after the Transition when MapView is showing, it is flipped 180 degree (see the screen shot below). How can I display the map normally without further rotating the map? I used Rotate3DAnimation.java Following is my code: Please help...
public class EventsActivity extends MapActivity implements DialogInterface.OnDismissListener {
private EventsItemModel eventsItemModel;
private Integer eventItemId;
private Integer eventCategoryId;
private static MapOverlay mapOverlay;
Drawable marker;
Context context;
private static String MY_LOCATION = "My Location";
private ViewGroup mContainer;
private ImageView mImageView;
private MapView mMapView;
private static boolean isFlipped = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.event_item_detail);
mContainer = (ViewGroup) findViewById(R.id.event_container);
// Since we are caching large views, we want to keep their cache
// between each animation
mContainer.setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE);
mMapView = (MapView) findViewById(R.id.mapview);
mImageView = (ImageView) findViewById(R.id.mapPreview);
mImageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
isFlipped = true;
applyRotation(1, 0, 90);
}
});
try {
eventCategoryId = getIntent().getIntExtra(AppConstants.EVENT_CATEGORY, 0);
eventItemId = getIntent().getIntExtra(AppConstants.EVENT_ID, 0);
}
catch (Exception e) {
e.printStackTrace();
}
}
public void onResume() {
super.onResume();
WeakReference<EventsActivity> weakContext = new WeakReference<EventsActivity>(this);
EventsAsyncTask task = new EventsAsyncTask(weakContext);
task.execute(eventItemId, eventCategoryId);
}
public void onTaskComplete(EventsItemModel eiModel) {
this.eventsItemModel = eiModel;
TextView calTitle = (TextView) findViewById(R.id.news_title);
TextView eventTitle = (TextView) findViewById(R.id.cal_event_title);
TextView calDate = (TextView) findViewById(R.id.cal_date);
TextView calTime = (TextView) findViewById(R.id.cal_time);
TextView calAddress = (TextView) findViewById(R.id.cal_address);
TextView calDescription = (TextView) findViewById(R.id.cal_description);
try {
calTitle.setText(eventsItemModel.getEventsCategory().getTitle());
calTitle.setVisibility(View.VISIBLE);
eventTitle.setText(eventsItemModel.getEventTitle());
calDate.setText(eventsItemModel.getFormattedDateRange());
// TODO:Format start and end time
calTime.setText("Time: " + eventsItemModel.getFormattedStartTime() + " - " + eventsItemModel.getFormattedEndTime());
calAddress.setText(eventsItemModel.getAddress());
calDescription.setText(eventsItemModel.getDescription());
System.out.println("<<<<<<<<< EventsActivity >>>>>>>>> isRead? " + eventsItemModel.getReadUnread());
eventsItemModel.setReadUnread(true);
System.out.println("<<<<<<<<<< EventsActivity >>>>>>>>>> isRead? " + eventsItemModel.getReadUnread());
}
catch (Exception e) {
e.printStackTrace();
}
mMapView.setBuiltInZoomControls(true);
setMapParameters();
createItemizedOverlay();
setLocationMarker(createMarker(R.drawable.location_marker));
showLocationPointOnMap();
}
#Override
public void onDismiss(DialogInterface dialog) {
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
public void createItemizedOverlay() {
mapOverlay = new MapOverlay(this);
}
public void setLocationMarker(Drawable marker) {
mapOverlay.setLocationMarker(marker);
}
public void showLocationPointOnMap() {
GeoPoint geoPoint = new GeoPoint(0, 0);
if (eventsItemModel != null && eventsItemModel.getLatitude() != null && eventsItemModel.getLatitude().length() > 0 && eventsItemModel.getLongitude() != null
&& eventsItemModel.getLongitude().length() > 0) {
try {
geoPoint = new GeoPoint((int) (Double.parseDouble(eventsItemModel.getLatitude()) * 1E6), (int) (Double.parseDouble(eventsItemModel.getLongitude()) * 1E6));
}
catch (NumberFormatException e) {
e.printStackTrace();
}
OverlayItem item = new OverlayItem(geoPoint, MY_LOCATION, null);
mapOverlay.addItem(item);
mMapView.getOverlays().add(mapOverlay);
// move to location
mMapView.getController().animateTo(geoPoint);
// redraw map
mMapView.postInvalidate();
}
}
public void setStreetView(boolean isStreetView) {
mMapView.setStreetView(isStreetView);
}
public void setSatelliteView(boolean isSatelliteView) {
mMapView.setSatellite(isSatelliteView);
}
public void setZoom(int zoomLevel) {
mMapView.getController().setZoom(zoomLevel);
}
private void setMapParameters() {
// setStreetView(true);
// setSatelliteView(false);
setZoom(17);
}
private Drawable createMarker(int iconID) {
// Initialize icon
Drawable icon = getResources().getDrawable(iconID);
icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
return icon;
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
/**
* Setup a new 3D rotation on the container view.
*
* #param position
* the item that was clicked to show a picture, or -1 to show the list
* #param start
* the start angle at which the rotation must begin
* #param end
* the end angle of the rotation
*/
private void applyRotation(int position, float start, float end) {
// Find the center of the container
final float centerX = mContainer.getWidth() / 2.0f;
final float centerY = mContainer.getHeight() / 2.0f;
// Create a new 3D rotation with the supplied parameter
// The animation listener is used to trigger the next animation
final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true);
rotation.setDuration(500);
rotation.setFillAfter(true);
rotation.setInterpolator(new AccelerateInterpolator());
rotation.setAnimationListener(new DisplayNextView(position));
mContainer.startAnimation(rotation);
}
/**
* This class listens for the end of the first half of the animation. It then posts a new action that effectively swaps the views when the container is rotated 90 degrees and thus invisible.
*/
private final class DisplayNextView implements Animation.AnimationListener {
private final int mPosition;
private DisplayNextView(int position) {
mPosition = position;
}
public void onAnimationStart(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
mContainer.post(new SwapViews(mPosition));
}
public void onAnimationRepeat(Animation animation) {
// Do nothing!!
}
}
/**
* This class is responsible for swapping the views and start the second half of the animation.
*/
private final class SwapViews implements Runnable {
private final int mPosition;
public SwapViews(int position) {
mPosition = position;
}
public void run() {
final float centerX = mContainer.getWidth() / 2.0f;
final float centerY = mContainer.getHeight() / 2.0f;
Rotate3dAnimation rotation;
if (mPosition > -1) {
mImageView.setVisibility(View.GONE);
mMapView.setVisibility(View.VISIBLE);
mMapView.requestFocus();
rotation = new Rotate3dAnimation(90, 180, centerX, centerY, 310.0f, false);
rotation.reset();
}
else {
mMapView.setVisibility(View.GONE);
mImageView.setVisibility(View.VISIBLE);
mImageView.requestFocus();
rotation = new Rotate3dAnimation(90, 0, centerX, centerY, 310.0f, false);
}
rotation.setDuration(100);
rotation.setFillAfter(true);
rotation.setInterpolator(new DecelerateInterpolator());
mContainer.startAnimation(rotation);
}
}
#Override
public void onBackPressed() {
if (isFlipped) {
applyRotation(-1, 180, 90);
isFlipped = false;
}
else {
super.onBackPressed();
}
}
}
The solution I found was as follows, any other elegant solution is highly appreciated:
Changed the degree of rotation as follows:
if (mPosition > -1) {
mImageView.setVisibility(View.GONE);
mMapView.setVisibility(View.VISIBLE);
mMapView.requestFocus();
rotation = new Rotate3dAnimation(-90, 0, centerX, centerY, 310.0f, false);
rotation.reset();
}
and
#Override
public void onBackPressed() {
if (isFlipped) {
applyRotation(-1, 0, -90);
isFlipped = false;
}
else {
super.onBackPressed();
}
}
That's it!! :)

Categories

Resources