0

I'm working on this app:

It gets a speed update every second. When speed is 120 km/h I want the happy face (an ImageView) to be on the top, and when speed is -120 km/h, it should be on the bottom. 0 km/h would be the center and so on for every speed.

Speed Bar

I calculated a relation betweeen km/h and pixels and move the face like this:

float pxSpeedFloat = -4.375 * speed + 115;
faceImageView.setY( -pxSpeedFloat);

setY(115) is the center of the bar, this equation works fine on Xperia Z1.

The problem is that it just work for this screen resolution, it doesn't fit other phones.

According to documentation, setY just admits value in pixels, not in % of the screen.

How do I solve it?

Yasin Kaçmaz
  • 6,573
  • 5
  • 40
  • 58
Daniel Viaño
  • 485
  • 1
  • 9
  • 26

3 Answers3

0

try multiplying by screen density

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

faceImageView.setY(-pxSpeedFloat * metrics.density);
Adonys
  • 123
  • 5
0

You can use this code to get the screen height:

DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int deviceHeight = displaymetrics.heightPixels;

Then you could just work your way from that. This code would position your ImageView at the bottom of the screen:

imageView.setY(deviceHeight - imageView.getHeight())

And this code would center it vertically

imageView.setY((deviceHeight * 0.5) - (imageView.getHeight() * 0.5))
Tharkius
  • 2,744
  • 2
  • 20
  • 31
  • This would work great for that three positions, but not for another random one. Thanks anyway, maybe knowing device height I can work in something... – Daniel Viaño Jun 29 '16 at 23:42
0

Okey i used FrameLayoutand measured its height. I dont konw if its efficient way but its working, maybe you can use AsyncTask with it, actually its 5am in here and i have an exam. So tried this and working perfect. You can try too and come with result maybe this will fix your problem, or i will take a look at it after my exam.

  1. Your global variables :

    FrameLayout frameLayout; int layoutheight; float MAX_SPEED=120; float MIN_SPEED=-120; float NEUTRAL_SPEED=0; float speed;

  2. in onCreate the point is here : getwidth-and-getheight-of-view

    image=(ImageButton)findViewById(R.id.icon);

    frameLayout =(FrameLayout) findViewById(R.id.frame); frameLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //when layout ready for measuring height //you must wait this frameLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); layoutheight= frameLayout.getHeight()/2; //height is ready Toast.makeText(getApplicationContext(),"height : "+layoutheight,Toast.LENGTH_LONG).show(); measureSpeed(-100);

         }
     });
    
  3. your measureSpeed method :

    public void measureSpeed(int speed){ //if speed equals 0 if(speed==NEUTRAL_SPEED){ FrameLayout.LayoutParams params=new FrameLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.gravity= Gravity.CENTER; image.setLayoutParams(params); } //if speed equals or less than -120 else if(speed<=MIN_SPEED){ FrameLayout.LayoutParams params=new FrameLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.gravity=Gravity.BOTTOM; image.setLayoutParams(params); } //if speed equals or greater than 120 else if(speed>=MAX_SPEED){ FrameLayout.LayoutParams params=new FrameLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.gravity=Gravity.TOP; image.setLayoutParams(params); } //otherwise else{ if(speed<NEUTRAL_SPEED){ //less than zero FrameLayout.LayoutParams params=new FrameLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.gravity=Gravity.CENTER; float rate=speed/MIN_SPEED; float marginsize=layoutheight*rate; params.topMargin=(int) marginsize; image.setLayoutParams(params);

         }
         //greater than zero
         else if(speed>NEUTRAL_SPEED){
             FrameLayout.LayoutParams params=new FrameLayout.LayoutParams(
                     ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
             params.gravity=Gravity.CENTER;
             float rate=speed/MAX_SPEED;
             float marginsize=layoutheight*rate;
             params.bottomMargin=(int) marginsize;
             image.setLayoutParams(params);
         }
     }
    

    }

  4. Example xml structure:

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Yasin Kaçmaz
  • 6,573
  • 5
  • 40
  • 58