I want to implement interactive TabPageIndicatot in android. I am using ViewPager.TabPageIndicator to make object of indicator.I am trying to implement scrollTo in TabPageIndicator class.
This is the code in my class. indicator is object of TabPageIndicator.
public void onPageScrolled(int pageNo, float arg1, final int arg2) {
// TODO Auto-generated method stub
indicator.scrollTo(arg2, 0);
}
This is the code in TabPageIndicator class.
private void animateToTab(final int x) {
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
mTabSelector = new Runnable() {
public void run() {
// final int scrollPos = tabView.getLeft() - (getWidth() - tabView.getWidth()) / 2;
smoothScrollTo(x, 0);
mTabSelector = null;
}
};
post(mTabSelector);
}
#Override
public void scrollTo(int x, int y) {
// TODO Auto-generated method stub
super.scrollTo(x, y);
//Log.i("Hi", Integer.toString(x));
animateToTab(x);
}
Here animateToTab() function is called infinite times. Why?
Related
I'm trying to implement Navigation Drawer using Drawer Layout without Action Bar.
Everything went smooth until i figured out that the drawer image didn't animate/slide like YouTube or Google Plus app.
What i meant with drawer image
Then i tried to implement my custom DrawerListener. Here is my activity class.
lstMenuDrawer.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
selectMenu(pos);
}
});
drawerToggle = new GRHDrawerToggle(MainActivity.this, imvDrawer.getDrawable());
drawerLayout.setDrawerListener(drawerToggle);
And here is my listener class
public class GRHDrawerToggle implements DrawerListener {
private Activity mActivity;
private SlideDrawable mSlider;
/** Fraction of its total width by which to offset the toggle drawable. */
private static final float TOGGLE_DRAWABLE_OFFSET = 1 / 3f;
public GRHDrawerToggle(Activity activity, Drawable drawerImage){
mActivity = activity;
mSlider = new SlideDrawable(drawerImage);
mSlider.setOffset(TOGGLE_DRAWABLE_OFFSET);
}
#Override
public void onDrawerClosed(View arg0) {
// TODO Auto-generated method stub
mSlider.setPosition(0);
}
#Override
public void onDrawerOpened(View arg0) {
// TODO Auto-generated method stub
mSlider.setPosition(1);
}
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
// TODO Auto-generated method stub
float glyphOffset = mSlider.getPosition();
if (slideOffset > 0.5f) {
glyphOffset = Math.max(glyphOffset, Math.max(0.f, slideOffset - 0.5f) * 2);
} else {
glyphOffset = Math.min(glyphOffset, slideOffset * 2);
}
mSlider.setPosition(glyphOffset);
}
#Override
public void onDrawerStateChanged(int arg0) {
// TODO Auto-generated method stub
}
private class SlideDrawable extends InsetDrawable implements Drawable.Callback {
private final boolean mHasMirroring = Build.VERSION.SDK_INT > 18;
private final Rect mTmpRect = new Rect();
private float mPosition;
private float mOffset;
private SlideDrawable(Drawable wrapped) {
super(wrapped, 0);
}
/**
* Sets the current position along the offset.
*
* #param position a value between 0 and 1
*/
public void setPosition(float position) {
mPosition = position;
invalidateSelf();
}
public float getPosition() {
return mPosition;
}
/**
* Specifies the maximum offset when the position is at 1.
*
* #param offset maximum offset as a fraction of the drawable width,
* positive to shift left or negative to shift right.
* #see #setPosition(float)
*/
public void setOffset(float offset) {
mOffset = offset;
invalidateSelf();
}
#Override
public void draw(Canvas canvas) {
copyBounds(mTmpRect);
canvas.save();
// Layout direction must be obtained from the activity.
final boolean isLayoutRTL = ViewCompat.getLayoutDirection(
mActivity.getWindow().getDecorView()) == ViewCompat.LAYOUT_DIRECTION_RTL;
final int flipRtl = isLayoutRTL ? -1 : 1;
final int width = mTmpRect.width();
canvas.translate(-mOffset * width * mPosition * flipRtl, 0);
// Force auto-mirroring if it's not supported by the platform.
if (isLayoutRTL && !mHasMirroring) {
canvas.translate(width, 0);
canvas.scale(-1, 1);
}
super.draw(canvas);
canvas.restore();
}
}
}
But still no sliding animation in my drawer button.
And then i realized method draw(Canvas canvas) in my listener class was never triggered.
Can someone tell me please where is my errors?
Many thanks.
gellaps
Hi im having a bit of problems getting my sprite to fade back in. Im using paralell entity modifiers, scaling and fading after which the sprite gets new X and Y cordinates and fades in and scales back up. It doesnt work and i think it might have something to do with the onUpdate method.
XOsprite = new Sprite(x, y, XO, engine.getVertexBufferObjectManager()) {
#Override
public boolean onAreaTouched(final TouchEvent te, final float xVal,
final float yVal) {
XOsprite.registerEntityModifier(downOut); //kill sprite
isKilled = true;
XOsprite.registerUpdateHandler(new IUpdateHandler() {
#Override
public void reset() {
// TODO Auto-generated method stub
}
#Override
public void onUpdate(float pSecondsElapsed) {
// TODO Auto-generated method stub
totalElapsedTime += pSecondsElapsed;
if(totalElapsedTime >= 3.0f){
BaseGameActivity gameActivity = (BaseGameActivity) activity;
gameActivity.runOnUpdateThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
if(isKilled){
reviveSprite();
isKilled = false;
}
}
});
}
//reset();
}
});
return true;
}
};
XOsprite.registerEntityModifier(inUp);
gameScene.attachChild(XOsprite);
gameScene.registerTouchArea(XOsprite);
return gameScene;
}
-edit- more code
public void reviveSprite(){
setSprites();
XOsprite.unregisterEntityModifier(downOut);
XOsprite.registerEntityModifier(inUp);
}
public void setSprites(){
if (rand.nextInt(2) == 0) {
XO = X;
} else {
XO = O;
}
x = rand.nextInt(MainActivity.CAM_WIDTH);
y = rand.nextInt(MainActivity.CAM_HEIGHT);
}
you are already on the UpdateThread, so no need to do this
gameActivity.runOnUpdateThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
if(isKilled){
reviveSprite();
isKilled = false;
}
}
});
just do this
if(isKilled){
reviveSprite();
isKilled = false;
}
I am working on frame animation in which i am using thread but thread is throwing me error .
my code is as follow ....
public class Newton_LawsActivity extends Activity implements OnTouchListener, OnGestureListener,OnDoubleTapListener {
/** Called when the activity is first created. */
OnTouchListener l;
ImageView animation;
ImageView hideimage;
TextView t;
Thread timer;
int Rid;
double pixel;
String law="null";
private GestureDetector gestureDetector;
float x,y;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gestureDetector = new GestureDetector(this);
// the frame-by-frame animation defined as a xml file within the drawable folder
animation = (ImageView)findViewById(R.id.image);
//animation.setBackgroundResource(R.drawable.anatomy_5);
hideimage=(ImageView)findViewById(R.id.imagein);
t=(TextView) findViewById(R.id.t);
animation.setBackgroundResource(R.anim.startanimation);
final AnimationDrawable newtonAnimation = (AnimationDrawable) animation.getBackground();
AnimationStart(newtonAnimation);
animation.setOnTouchListener(this);
}
public void AnimationStart(final AnimationDrawable newanimation){
timer=new Thread(){
#Override
public void run(){
try{
}catch(Exception e){}
finally{
Newton_LawsActivity.this.runOnUiThread(new Runnable() {
public void run(){
newanimation.start();
}});
}
}
};
timer.start();
}
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
Toast.makeText(this, "animation", Toast.LENGTH_LONG).show();
return gestureDetector.onTouchEvent(event);
}
private void animationswitch(float x, float y) {
// TODO Auto-generated method stub
pixel = getmaskpixel(x,y,animation,hideimage);
Log.w("DEBUG","which is null:pixel" + pixel );
if (pixel==-583672){
animation.setBackgroundResource(R.anim.firstlaw_01);
final AnimationDrawable firstlaw_01 = (AnimationDrawable) animation.getBackground();
law="firstlaw_02";
firstlaw_01.start();
animationstop_01();
}
t.setText(Double.toString(pixel));
}
private double getmaskpixel(float x, float y, ImageView view,ImageView hideimage) {
// TODO Auto-generated method stub
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.touchnewtonfinal415);
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) view.getWidth()) / width;
float scaleHeight = ((float) view.getHeight()) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// matrix.postRotate(90);
// recreate the new Bitmap
Bitmap bitmap = Bitmap.createBitmap(bm, 0, 0, width, height,matrix, false);
Log.w("DEBUG","which is null:image " + hideimage.getWidth() + " OR " +hideimage.getHeight() );
double bmWidth = view.getWidth();
double bmHeight = view.getHeight();
if ( x < 0 || y < 0 || x > hideimage.getWidth() || y >hideimage.getHeight()){
return 0; //Invalid, return 0
}else{
//Convert touched x, y on View to on Bitmap
int xBm = (int)(x * (bmWidth / hideimage.getWidth()));
int yBm = (int)(y * (bmHeight / hideimage.getHeight()));
return bitmap.getPixel((int)xBm,(int) yBm);
}
}
public boolean onSingleTapUp(MotionEvent e) {
return false;
// TODO Auto-generated method stub
}
#Override
public boolean onDown(MotionEvent arg0) {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
// TODO Auto-generated method stub
return false;
}
#Override
public void onLongPress(MotionEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
// TODO Auto-generated method stub
return false;
}
#Override
public void onShowPress(MotionEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public boolean onDoubleTap(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onDoubleTapEvent(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// TODO Auto-generated method stub
x=e.getX();
y= e.getY();
Log.w("DEBUG","which is null:image " + x + " OR " +y);
animationswitch(x, y);
return true;
}
void animationstop_01(){
if(law=="firstlaw_02"){
timer=new Thread(){
#Override
public void run(){
try{
Thread.sleep(8750);
}catch(Exception e){}
finally{
Log.w("debug","it is firstlaw_02");
animation.setBackgroundResource(R.anim.firstlaw_02);
final AnimationDrawable firstlaw_02 = (AnimationDrawable) animation.getBackground();
law="firstlaw_03";
AnimationStart(firstlaw_02);
}};
};
timer.start();
}
}
}
it is throwing me following error..
06-06 14:15:00.668: E/AndroidRuntime(966): FATAL EXCEPTION: Thread-10
06-06 14:15:00.668: E/AndroidRuntime(966): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.ViewRoot.invalidateChild(ViewRoot.java:607)
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:633)
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.View.invalidate(View.java:5139)
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.View.setBackgroundDrawable(View.java:7486)
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.View.setBackgroundResource(View.java:7395)
06-06 14:15:00.668: E/AndroidRuntime(966): at Newtons.law.Newton_LawsActivity$2.run(Newton_LawsActivity.java:183)
Change your animationstop_01 method to:
void animationstop_01(){
if(law=="firstlaw_02"){
timer=new Thread(){
#Override
public void run(){
try{
Thread.sleep(8750);
}catch(Exception e){
}finally{
Log.w("debug","it is firstlaw_02");
Newton_LawsActivity.this.runOnUiThread(new Runnable() {
public void run(){
animation.setBackgroundResource(R.anim.firstlaw_02);
final AnimationDrawable firstlaw_02 = (AnimationDrawable) animation.getBackground();
law="firstlaw_03";
AnimationStart(firstlaw_02);
}
});
}
};
};
timer.start();
}
}
Error is inside the mehod name animationstop_01() where you are trying,
animation.setBackgroundResource(R.anim.firstlaw_02);
put that inside runOnUiThread()
try this:
animation.post(new Runnable() {
public void run() {
animation.setBackgroundResource(R.anim.firstlaw_02);
}
});
In that way you are posting it to the UI thread. View can only be changed from the original thread that created the View.
i developed a map who can rotate the direction view depend where the user face (example, if the user turn into south,than map will rotating to south direction, like compass). I already tried this project with minimal success for a couple week. I have no error message on eclipse,but when i debug the code, the application always crash.
Thanks,i really need all the help
private class RotateView extends ViewGroup {
private Matrix mMatrix = new Matrix();
private float[] mTemp = new float [2];
private static final float SQ2 = 1.414213562373095f;
public RotateView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
#Override
protected void dispatchDraw(Canvas canvas) {
// TODO Auto-generated method stub
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.rotate(-mHeading,getWidth()*0.5f , getHeight()*0.5f);
canvas.getMatrix(mMatrix);
super.dispatchDraw(canvas);
canvas.restore();
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
final int width = getWidth();
final int height = getHeight();
final int count = getChildCount();
for (int i=0; i<=count; i++){
final View view = getChildAt(i);
final int childWidth = view.getMeasuredWidth();
final int childHeight = view.getMeasuredHeight();
final int childLeft = ((width - childWidth)/2);
final int childTop = ((height-childHeight)/2);
view.layout(childLeft, childTop, childLeft+childWidth, childTop+childHeight);
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
int mW = getDefaultSize(getMeasuredWidth(), widthMeasureSpec);
int mH = getDefaultSize(getMeasuredHeight(), heightMeasureSpec);
int sizeSpec;
if(mW > mH){
sizeSpec = MeasureSpec.makeMeasureSpec((int)(mW*SQ2), MeasureSpec.EXACTLY);
} else {
sizeSpec = MeasureSpec.makeMeasureSpec((int) (mH*SQ2), MeasureSpec.EXACTLY);
}
final int count = getChildCount();
for(int i = 0; i<count; i++){
getChildAt(i).measure(sizeSpec, sizeSpec);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
#Override
public boolean dispatchTouchEvent(MotionEvent e) {
// TODO Auto-generated method stub
return super.dispatchTouchEvent(e);
}
}
// End of class RotateView
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sensormanager =(SensorManager)getSystemService(SENSOR_SERVICE);
rotateview = new RotateView(this);
map = new MapView (this,"Map Key");
rotateview.addView(map);
setContentView(rotateview);
controll();
}
public void controll () {
controller = map.getController();
//Zoom
map.setBuiltInZoomControls(true);
controller.setZoom(19);
overlayList = map.getOverlays();
map.setClickable(true);
map.setEnabled(true);
//compass
compass = new MyLocationOverlay(MapIpbActivity.this, map);
overlayList.add(compass);
myLocation();
Touchy t = new Touchy();
overlayList.add(t);
}
public void myLocation() {
ourLocation = new MyLocationOverlay(MapIpbActivity.this, map);
map.getOverlays().add(ourLocation);
ourLocation.runOnFirstFix(new Runnable() {
public void run(){
controller.animateTo(ourLocation.getMyLocation());
}
});
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
compass.disableCompass();
ourLocation.disableMyLocation();
sensormanager.unregisterListener(orientListener);
super.onPause();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
compass.enableCompass();
ourLocation.enableMyLocation();
sensormanager.registerListener(orientListener,
sensormanager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
sensormanager.SENSOR_DELAY_NORMAL);
}
final SensorEventListener orientListener = new SensorEventListener() {
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
if(event.sensor.getType() == Sensor.TYPE_ORIENTATION){
mHeading = event.values[0];
rotateview.invalidate();
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
};
class Touchy extends Overlay {
long start;
long stop;
int x;
int y;
GeoPoint TouchedPoint;
#Override
public boolean onTouchEvent(MotionEvent e, MapView m) {
// TODO Auto-generated method stub
if(e.getAction() == MotionEvent.ACTION_DOWN) {
start = e.getEventTime();
x = (int) e.getX();
y = (int) e.getY();
TouchedPoint = map.getProjection().fromPixels(x, y);
}
if (e.getAction() == MotionEvent.ACTION_UP) {
stop = e.getEventTime();
}if (stop - start > 2000){
box();
return true;
}
return false;
}
Solved this, just change i<=count into i<count, and everything will work! But my zoom and compass didn't show.
I have code like this:
public class SnowFallService extends BaseLiveWallpaperService implements IOnAreaTouchListener{
// ===========================================================
// Constants
// ===========================================================
private static final int CAMERA_WIDTH = 480;
private static final int CAMERA_HEIGHT = 800;
private ArrayList<Sprite> allSnow = new ArrayList<Sprite>();
// ===========================================================
// Fields
// ===========================================================
private ScreenOrientation screenOrientation;
private static TextureRegion snowTexture;
private static TextureRegion backgroundTexture;
private static Textures texture = null;
private Scene mScene;
public org.anddev.andengine.engine.Engine onLoadEngine() {
return new org.anddev.andengine.engine.Engine(new EngineOptions(true, this.screenOrientation, new FillResolutionPolicy(), new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT)));
}
public void onLoadResources() {
texture = new Textures(this, getEngine());
}
public void onUnloadResources() {
}
public Scene onLoadScene() {
final Scene mScene = new Scene();
backgroundTexture = texture.getBackground();
mScene.attachChild(new Sprite(0, 0, backgroundTexture));
snowTexture = texture.getSnowTextureRegion();
mScene.registerUpdateHandler(new IUpdateHandler() {
private long lastRaindropAdd = 0;
#Override
public void onUpdate(final float pSecondsElapsed) {
int size = allSnow.size();
int tmpInt = 0;
Random randGen = new Random();
for (int i = 0; i < size; i++) {
if (allSnow.get(i) != null){
Sprite snow = allSnow.get(i);
tmpInt = randGen.nextInt(4);
snow.setPosition(snow.getX() + (randGen.nextInt(5) - randGen.nextInt(5)) * randGen.nextInt(3), snow.getY() + tmpInt);
if (snow.getY() > CAMERA_HEIGHT || snow.getX() > CAMERA_WIDTH) {
synchronized(snow) {
size--;
allSnow.remove(i);
mScene.detachChild(snow);
}
}
}
}
tmpInt = randGen.nextInt(5000);
if (System.currentTimeMillis() - lastRaindropAdd > tmpInt) {
lastRaindropAdd = System.currentTimeMillis();
tmpInt = randGen.nextInt(CAMERA_WIDTH);
Sprite snow = getRaindrop(tmpInt, 0);
allSnow.add(snow);
mScene.attachChild(snow);
}
}
#Override
public void reset() {
}
});
return mScene;
}
public void onLoadComplete() {
// TODO Auto-generated method stub
}
public void onPauseGame() {
// TODO Auto-generated method stub
}
public void onResumeGame() {
// TODO Auto-generated method stub
}
public Sprite getRaindrop(float x, float y) {
return (new Sprite(x, y, snowTexture.deepCopy()));
}
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,ITouchArea pTouchArea, float pTouchAreaLocalX, float pTouchAreaLocalY) {
if(pSceneTouchEvent.isActionDown()) {
// HERE I WANT PLACE CODE, THAT WILL START ANIMATION.
return true;
}
return false;
}
}
So how to start animation on click? I want to make something like small cartoon.
In your onLoadScene method after registering update handler disable it.
mUpdateHandler.setEnabled(false);
And in onAreaTouched method enable it.
mUpdateHandler.setEnabled(true);
Btw I think it's not good practice to create Random instance every time in onUpdate method.
Here Josh describes how to override onTouch method (andEngine does not handle touch events for livewallpaper correctly, so you have to do it on your own). In few words, all you have to do is to override following function in BaseWallpaperGLEngine class (class is a part of andEngine live wallpaper extension:
#Override
public void onTouchEvent (MotionEvent event)
{
}