【问题标题】:How to programmatically displaying an image with a text (or button, or other) overlay?如何以编程方式显示带有文本(或按钮或其他)覆盖的图像?
【发布时间】:2011-11-20 22:58:31
【问题描述】:

我有一张要通过 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);
    } 
}

【问题讨论】:

    标签: android textview imageview overlay scrollview


    【解决方案1】:

    您可以扩展视图类并覆盖 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 方法中。这就是你粗略的做法。您需要进行一些修改或添加以使其适合您。

    【讨论】:

    • 这是一个想法,但这应该可以使用标准的 ImageView 和 TextView 类来实现......而且也没有那么复杂。同样,出于此目的,它可能是文本,但它也可以很容易地成为按钮或菜单或其他东西。我可以制作一个 ScrollView,我可以在其中放置一个 ImageView 和一个 TextView,但是我还没有让对齐工作......而且实际上,当它存在时,textview 应该独立地覆盖 Scrollview。
    • 在这种情况下,最简单的解决方案使用框架布局。它将根据其顺序将其子视图绘制在彼此之上。
    • FrameLayout 做的和RelativeLayout 是一样的:文本卡在角落而不是屏幕中间,它随着滚动而移动。我需要叠加的文本出现并保持在中心,与下面的滚动状态无关。在某种程度上,它就像一个吐司,但同样,它可能是一个按钮或其他一些比覆盖下图的文本更复杂的对象。
    • 注意:我赞成,但我还没有足够的声誉......我正在通过 XML 对 FrameLayout 进行一些测试,但我真的很想看到一种编程方式来完成这个.
    • 它现在似乎工作得更好了......再次感谢您的有用建议!如果可以的话,请给我点赞。
    猜你喜欢
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 2023-03-18
    • 2020-05-19
    相关资源
    最近更新 更多