如何以编程方式显示带有文本(或按钮或其他)覆盖的图像?

发布于 2024-12-05 06:18:34 字数 4870 浏览 1 评论 0原文

我有一个图像要通过 ImageView 元素显示。根据用户输入(例如,长按),我想要在该图像上叠加一些内容,使得叠加层位于屏幕中间(或者至少位于左上角以外的其他位置......但是关键是它覆盖图像并且我可以在代码中选择该位置它可能是一个信息丰富的 TextView 项目(但不是 Toast),或一些临时缩放按钮。

这最终都将成为某种 ScrollView 的子级(可能是 TwoDScrollView ,但如果您有更好的建议请告诉我),因此无论放置什么文本或按钮都不应排除这种可能性。但 WebView 不是一个选项。除非您有更好的建议,否则我可能会使用RelativeLayout。

我想以编程方式执行此操作,而不是使用 XML。我不期望任何人提供完整的程序(除非已经存在......但我还没有找到)。我只需要一个明确的轮廓,说明如何对图像上的某些文本正确实现这一点。

编辑:我一整天都在寻找,找到了很多想法,但它们要么是纯 XML 的,要么与我在这里尝试做的完全不同。但是,如果您有合适的指针,请告诉我!

编辑 2:这是我创建的一个工作示例,它实现了我想要完成的任务。希望这对其他人有用! animage1 是一个 1000x1000px 的图像...重点是它比您使用的屏幕大。 animage2 相对较小(100x100px)。 “菜单”被重载以切换第二个图像的可见性作为概念证明。

package com.myname.testoverlay2;

//import android.widget.HorizontalScrollView; // Works with this as well

import com.myname.testoverlay2.TwoDScrollView;
// From - http://blog.gorges.us/2010/06/android-two-dimensional-scrollview/
//     with fix added from comments there

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.ImageView;

public class Testoverlay2Activity extends Activity {
    private static final String TAG = "MyApp";

    ImageView iv2;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        FrameLayout fl1 = new FrameLayout(this);
        FrameLayout.LayoutParams flp1 = new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        fl1.setId(9001);
        fl1.setLayoutParams(flp1);

        TwoDScrollView sv1 = new TwoDScrollView(this);
        sv1.setId(9002);

        FrameLayout fl2 = new FrameLayout(this);
        FrameLayout.LayoutParams flp2 = new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        fl2.setId(9003);
        fl2.setLayoutParams(flp2);

        ImageView iv1 = new ImageView(this);
        FrameLayout.LayoutParams ivp1 = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        iv1.setId(9004);
        iv1.setLayoutParams(ivp1);
        Bitmap bm1 = BitmapFactory.decodeResource(getResources(),
            getResources().getIdentifier("animage1" , "drawable", getPackageName()));
        iv1.setImageBitmap(bm1);
        //Log.d(TAG, "Bitmap1 = (" + bm1.getWidth() + ", " + bm1.getHeight() + ")");

        iv2 = new ImageView(this);
        FrameLayout.LayoutParams ivp2 = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER);
        iv2.setId(9005);
        iv2.setLayoutParams(ivp2);
        Bitmap bm2 = BitmapFactory.decodeResource(getResources(),
            getResources().getIdentifier("animage2" , "drawable", getPackageName()));
        iv2.setImageBitmap(bm2);
        //Log.d(TAG, "Bitmap2 = (" + bm2.getWidth() + ", " + bm2.getHeight() + ")");

        // Lay everything out
        fl1.addView(sv1);
        fl1.addView(iv2);
        sv1.addView(fl2);
        fl2.addView(iv1);
        setContentView(fl1);

        // The following is based on a StackOverflow comment that scrollTo won't work immediately, in general...
        // http://stackoverflow.com/questions/4720469/horizontalscrollview-auto-scroll-to-end-when-new-views-are-added
        Handler mHandler = new Handler();
        mHandler.postDelayed(new Runnable() {
            public void run() {
                TwoDScrollView container=(TwoDScrollView)findViewById(9002);
                if (container != null) {
                    Log.d(TAG, "executing scrollTo()");
                    //container.setOverScrollMode(TwoDScrollView.OVER_SCROLL_IF_CONTENT_SCROLLS); // Needed?
                    container.scrollTo(500,500);
                }
                else {
                    Log.d("MyApp", "Container is null");
                }
            }
        }, 100L);  
    }

    // Keyboard wedge for testing convenience
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.d(TAG, "Keypress = (" + keyCode + ")");
        switch (keyCode) {
        case KeyEvent.KEYCODE_MENU:
            /* Sample for handling the Menu button globally */
            if (iv2.getVisibility() == ImageView.VISIBLE) {
                iv2.setVisibility(ImageView.INVISIBLE);             
            }
            else {
                iv2.setVisibility(ImageView.VISIBLE);
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    } 
}

I have an image to display via an ImageView element. Based on user input (say, a long press) I will want to overlay something on that image, such that the overlay is in the middle of the screen (or somewhere other than the upper-left corner at least... but the key is that it overlays the image and that I can choose that location in code. It might be an informative TextView item (not a Toast though), or some ephemeral zoom buttons).

This will all eventually be a child of a ScrollView of some kind (likely TwoDScrollView, but if you have a better suggestion let me know), so whatever text or button gets put up should not exclude that possibility. WebView is not an option though. I'd probably use a RelativeLayout unless you have a better suggestion.

I want to do this programmatically - not in XML. I don't expect a full program from anyone (unless one already exists... I haven't found one yet though). I just need a solid outline of how to make this happen properly for some text over an image.

Edit: I've been looking all day and I've found many ideas but they are either XML-only or completely different than what I'm trying to do here. If, however, you have a pointer to something appropriate please let me know!

Edit 2: Here's a working example I created that does what I set out to accomplish. Hopefully this will be useful to others! animage1 is a 1000x1000px image... the point is it's larger than the screen you're using. animage2 is relatively small (100x100px). "Menu" is overloaded to toggle the visibility of that second image as a proof of concept.

package com.myname.testoverlay2;

//import android.widget.HorizontalScrollView; // Works with this as well

import com.myname.testoverlay2.TwoDScrollView;
// From - http://blog.gorges.us/2010/06/android-two-dimensional-scrollview/
//     with fix added from comments there

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.ImageView;

public class Testoverlay2Activity extends Activity {
    private static final String TAG = "MyApp";

    ImageView iv2;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        FrameLayout fl1 = new FrameLayout(this);
        FrameLayout.LayoutParams flp1 = new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        fl1.setId(9001);
        fl1.setLayoutParams(flp1);

        TwoDScrollView sv1 = new TwoDScrollView(this);
        sv1.setId(9002);

        FrameLayout fl2 = new FrameLayout(this);
        FrameLayout.LayoutParams flp2 = new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        fl2.setId(9003);
        fl2.setLayoutParams(flp2);

        ImageView iv1 = new ImageView(this);
        FrameLayout.LayoutParams ivp1 = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        iv1.setId(9004);
        iv1.setLayoutParams(ivp1);
        Bitmap bm1 = BitmapFactory.decodeResource(getResources(),
            getResources().getIdentifier("animage1" , "drawable", getPackageName()));
        iv1.setImageBitmap(bm1);
        //Log.d(TAG, "Bitmap1 = (" + bm1.getWidth() + ", " + bm1.getHeight() + ")");

        iv2 = new ImageView(this);
        FrameLayout.LayoutParams ivp2 = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER);
        iv2.setId(9005);
        iv2.setLayoutParams(ivp2);
        Bitmap bm2 = BitmapFactory.decodeResource(getResources(),
            getResources().getIdentifier("animage2" , "drawable", getPackageName()));
        iv2.setImageBitmap(bm2);
        //Log.d(TAG, "Bitmap2 = (" + bm2.getWidth() + ", " + bm2.getHeight() + ")");

        // Lay everything out
        fl1.addView(sv1);
        fl1.addView(iv2);
        sv1.addView(fl2);
        fl2.addView(iv1);
        setContentView(fl1);

        // The following is based on a StackOverflow comment that scrollTo won't work immediately, in general...
        // http://stackoverflow.com/questions/4720469/horizontalscrollview-auto-scroll-to-end-when-new-views-are-added
        Handler mHandler = new Handler();
        mHandler.postDelayed(new Runnable() {
            public void run() {
                TwoDScrollView container=(TwoDScrollView)findViewById(9002);
                if (container != null) {
                    Log.d(TAG, "executing scrollTo()");
                    //container.setOverScrollMode(TwoDScrollView.OVER_SCROLL_IF_CONTENT_SCROLLS); // Needed?
                    container.scrollTo(500,500);
                }
                else {
                    Log.d("MyApp", "Container is null");
                }
            }
        }, 100L);  
    }

    // Keyboard wedge for testing convenience
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.d(TAG, "Keypress = (" + keyCode + ")");
        switch (keyCode) {
        case KeyEvent.KEYCODE_MENU:
            /* Sample for handling the Menu button globally */
            if (iv2.getVisibility() == ImageView.VISIBLE) {
                iv2.setVisibility(ImageView.INVISIBLE);             
            }
            else {
                iv2.setVisibility(ImageView.VISIBLE);
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    } 
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心碎的声音 2024-12-12 06:18:34

您可以扩展视图类并重写 ondraw 方法。使用画布,您可以绘制位图并在其上绘制文本。

据我了解,您需要让文本出现在中间并且独立于滚动视图。这是我要制作的 UI 结构

<FrameLayout>
    <ScrollView>
        <Imageview/>
    </ScrollView>
    <TextView/>
</FrameLayout>

要以编程方式创建此布局,大致就是这样做的。

    ViewGroup.LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, 
            LayoutParams.FILL_PARENT);

    ScrollView sv = new ScrollView(this);
    sv.setLayoutParams(lp);

    TextView tx = new TextView(this);
    tx.setLayoutParams(lp);
    tx.setGravity(Gravity.CENTER);
    tx.setText("Test");

    FrameLayout fr = new FrameLayout(this);        
    fr.setLayoutParams(lp);
    fr.addView(sv);
    fr.addView(tx);
    setContentView(fr);

上面的代码应该放在onCreate方法中。这就是你粗略地做的方法。您需要进行一些修改或添加才能使其适合您。

You can extend the view class and override the ondraw method. Using the canvas, you can draw a bitmap and also text on top of it.

From what i understood you need to have text appear in the middle and independent of the scrollview. This is the structure of the UI I would make

<FrameLayout>
    <ScrollView>
        <Imageview/>
    </ScrollView>
    <TextView/>
</FrameLayout>

To create this layout programatically, this is roughly how you do it.

    ViewGroup.LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, 
            LayoutParams.FILL_PARENT);

    ScrollView sv = new ScrollView(this);
    sv.setLayoutParams(lp);

    TextView tx = new TextView(this);
    tx.setLayoutParams(lp);
    tx.setGravity(Gravity.CENTER);
    tx.setText("Test");

    FrameLayout fr = new FrameLayout(this);        
    fr.setLayoutParams(lp);
    fr.addView(sv);
    fr.addView(tx);
    setContentView(fr);

The above code should go in the onCreate method. This is just how you do it roughly. You will need to make some modifications or additions to make it work for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文