How to get same co-ordinates for image for all res

2019-03-27 18:01发布

问题:

I stucked with getting x & y co-ordinates of an image for all resolutions.

  1. 320, for devices with screen configurations such as:
    • 240x320 ldpi (QVGA handset)
    • 320x480 mdpi (handset)
    • 480x800 hdpi (high density handset)
  2. 480, for screens such as 480x800 mdpi (tablet/handset).
  3. 600, for screens such as 600x1024 mdpi (7" tablet).
  4. 720, for screens such as 720x1280 mdpi (10" tablet).

I have created my image view with original size of an image like 1500 x 1119. When i touched the image i can get the co-ordinates using by onTouch(). My issue if the co-ordinates are changed in all device. I am getting different x & y values in different deceives . I can't get same x & y values for all the resolutions. How can i resolve this?

回答1:

Here's a slightly more generic solution than your particular layout requires. This assumes you know the dimensions of the source image and want to know the coordinates on it that were tapped, ignoring screen size and resolution. Although your layout has defined width and height that appears to match the source image, this will handle layouts with width and height set to either wrap_content or match_parent, provided you're using one of the scale types that fits the whole image inside the view bounds and preserves the aspect ratio (e.g. fitXY).

I haven't tried this inside ScrollViews as you have yours but in theory it should be fine.

int sourceWidth = 1500;
int sourceHeight = 1119;

// Find view dimensions
int width = view.getWidth();
int height = view.getHeight();

// Assuming image has been scaled to the smaller dimension to fit, calculate the scale
float wScale = (float)width/(float)sourceWidth;
float hScale = (float)height/(float)sourceHeight;
float scale = Math.min(wScale, hScale);

// Find the offset in the direction the image doesn't fill the screen
// For ImageViews that wrap the content, both offsets will be 0 so this is redundant
int offsetX = 0;
int offsetY = 0;
if (wScale <= hScale) {
    offsetY = (int)((height/2) - ((scale * sourceHeight)/2));
} else {
    offsetX = (int)((width/2) - ((scale * sourceWidth)/2));
}

// Convert event coordinates to image coordinates
int sourceX = (int)((event.getX() - offsetX) / scale);
int sourceY = (int)((event.getY() - offsetY) / scale);


回答2:

Finally I found the answer. I did like this.

Initially I have created my Layout like this.

new_lay.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical" >

<ScrollView
    android:id="@+id/sv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF"
    android:orientation="vertical" >

    <HorizontalScrollView
        android:id="@+id/hv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF" >

        <FrameLayout
            android:id="@+id/ground_gry_fl1"
            android:layout_width="3193dp"
            android:layout_height="1815dp"
            android:background="#FFFFFF" >

            <FrameLayout
                android:id="@+id/zoom_lay1"
                android:layout_width="3193dp"
                android:layout_height="1815dp"
                android:background="@drawable/mall_map" >

                <ImageView
                    android:id="@+id/marker_image"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/ic_launcher"
                    android:visibility="invisible" >
                </ImageView>
            </FrameLayout>
        </FrameLayout>
    </HorizontalScrollView>
</ScrollView>

NewClass .java

     public class NewClass extends Activity {

ImageView mark;

 FrameLayout ground_gry_fl,zoom_lay;
 ScrollView sv;

float val1 = 0.0f;
float val2 = 0.0f;

@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.new_lay);
    sv=(ScrollView) findViewById(R.id.sv);
    mark = (ImageView) findViewById(R.id.marker_image);
    ground_gry_fl = (FrameLayout)findViewById(R.id.ground_gry_fl1);
    zoom_lay = (FrameLayout)findViewById(R.id.zoom_lay1);
    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);

            int height = metrics.heightPixels;
    int width = metrics.widthPixels;

    System.out.println("width"+width);
        System.out.println("height"+height);

    float densityDpi = metrics.density;
            System.out.println("densityDpi" + densityDpi);

    val1 = densityDpi * 1064;  // here give random x value (co-ordinate)
    val2 = densityDpi * 1253;  // here give random y value (co-ordinate)


    System.out.println("val1" + val1);
    System.out.println("val2" + val2);          

    mark.setX(val1);
    mark.setY(val2);

    mark.setVisibility(View.VISIBLE);

}

}

It should place same place in all the resolution of the device. You can scroll the image and see the point. Its works finely for me.



回答3:

please set display density

    float density = getActivity().getResources().getDisplayMetrics().density;
    if (density == 4.0) {
        displayMetrixDensity = 640;
    }
    if (density == 3.0) {
        displayMetrixDensity = 480;
    }
    if (density == 2.0) {
        displayMetrixDensity = 320;
    }
    if (density == 1.5) {
        displayMetrixDensity = 160;
    }
    if (density == 1.0) {
        displayMetrixDensity = 160;
    }