简体   繁体   中英

How to implement image region click listener for multiple screen size in android?

I want to create fullscreen activity that load image ad in fullscreen. The example image is like this:

在此处输入图片说明

Note that, the button is also part of image. Here is the layout xml:

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

</LinearLayout>

You can see the image is loaded with android:background .

What I want to achieve is: when the "Button" image portion is clicked, it will do something (like launching another activity), as well as the "Close [X]" rectangle at top-right corner, when clicked, it will close the activity.

It seems it's easy to implement click logic on the region part of "Button" drawing. So far I found two ways:

  1. Set ontouch listener on LinearLayout and check it's X and Y coordinate for the Button drawing region

  2. Put invisible ImageView on top of "Button" image in layout, and set onclick listener.

But the problem is: there are multiple screen sizes and resolutions across many android devices. So I wonder if those two solusions can be used in portable way across different screen size?

Since the image might be stretched when loaded in different screen resolution, and that means for solution #1: I have to adjust X & Y number. And for solution #2: the invisible ImageView's position might get synched-off from the Button drawing.

So anyone know better solution for this?

UPDATE:

I'm trying to use invisible click placeholder solution. Here is the layout xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/ad_image"
    android:id="@+id/adLayout"
    android:weightSum="1">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.75"/>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.16"
        android:id="@+id/adImageLayout"
        android:onClick="adImageClicked">
    </LinearLayout>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
</LinearLayout>

adImageLayout is the click placeholder for the button drawing.

Or supply an image for each of the densities that android supports, and add layout that position the button accordingly for each Image Or much better yet just make the lower region of the image clickable. The button itself is big and almost cover the entire region of the lower screen. users will not try to click there if they don't want to click the button. I can tell you from first hand that this is what Ad companies doing in situations like that.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="your_background">

   <ImageButton
       android:layout_width="match_parent"
       android:layout_height="120dp"
       android:layout_alignParentBottom="true"
       android:background="#000"
    />
</RelativeLayout>

---- UPDATE ----

<FrameLayout 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"
            tools:context=".MainActivity">

<Button
    android:id="@+id/my_button"
    android:text="My Button"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/black"
    android:textColor="@android:color/white"
    android:gravity="center"
    android:layout_gravity="bottom"
    android:padding="24dp"
    />

</FrameLayout>

public class MainActivity extends Activity {

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.my_button);

        final int heightPixels = getResources().getDisplayMetrics().heightPixels;
        button.setTranslationY(- heightPixels / 3 / 2);
    }



}

I decided to answer my question. I improved my original solution:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/ad_image"
    android:weightSum="1">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.7">

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:src="@drawable/xbutton"
            android:onClick="xButtonClicked"/>
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.2">

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1.1" />

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="0.3"
            android:onClick="buttonClicked"/>

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1"/>
    </LinearLayout>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

Here is the schema of the Layout:

在此处输入图片说明

The close button is loaded with ImageView.

So basically I'm just using layout_weight trick here. I avoided hardcoded dpi, as it will cause different LinearLayout's width/height result in different screen size.

I have tested with several screen resolutions (except tablet size), it works fine. I don't need to supply different image and layout files for multiple densities. And the required code in the Activity class is very minimal, there are only code to set fullscreen:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                     WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);

and the onClick event methods.

Of course, if you can found better solution, let me know.

If you don't want to work with buttons and views, you could just think at X and Y in form of fractions of the whole screen width and height.

Let's say the clickable area goes from 1/3 to 2/3 of the screen width. Then you can just recall the actual ScreenWidth (in dp, pixels, or whatever) and say at runtime that the clickable area goes from (1/3)*ScreenWidth to (2/3)*ScreenWidth.

Same for Ys, or for the close button. Designer will then make the background according to these ratios.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM