【问题标题】:Android - bottom bar overlapping SurfaceViewAndroid - 底栏重叠 SurfaceView
【发布时间】:2013-11-08 13:52:48
【问题描述】:

好的,所以在我问这个问题之前,我看过:

How to remove unwanted overlapping in android

Tabs at bottom overlapping with the list view

Android bottom navigation bar overlapping Spinner. Set Spinner dropdown height / margin

Bottom button bar overlaps the last element of Listview!

但是,我还没有看到我认为可以解决我的特殊情况的方法。 所以这是我的问题:我正在编写一个将在屏幕上显示图像的自定义 SurfaceView。在那个 SurfaceView 中,我在右下角绘制图像。代码如下:

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.os.Build;
import android.os.Bundle;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;

public class demosf extends Activity {

    OurView v;
    int Measuredwidth;
    int Measuredheight;
    WindowManager w;
    Bitmap whatever;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Measuredwidth = 0;
        Measuredheight = 0;
        getScreenWidthAndHeight();
        whatever = BitmapFactory.decodeResource(getResources(), R.raw.dragarrow);
        v = new OurView(this);
        setContentView(v);
    }

    public class OurView extends SurfaceView implements Runnable {

        Thread t = null;
        SurfaceHolder holder;
        boolean isItOK;
        public OurView(Context context) {
            super(context);
            holder = getHolder();
        }

        @Override
        public void run() {
            while (isItOK) {
                try {
                    Thread.sleep((long) 50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (!holder.getSurface().isValid()) {
                    continue;
                }
                Canvas c = holder.lockCanvas();
                c.drawARGB(255, 0, 0, 0);
                c.drawBitmap(whatever, ((float) Measuredwidth - (float) whatever.getWidth()), ((float) Measuredheight - (float) whatever.getHeight()), null);
                holder.unlockCanvasAndPost(c);
            }
        }
        public void pause() {
            isItOK = false;
            while (true) {
                try {
                    t.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            }
            t = null;
        }

        public void resume() {
            isItOK = true;
            t = new Thread(this);
            t.start();
        }
    }
    @Override
    protected void onPause() {
        super.onPause();
        v.pause();
    }
    @Override
    protected void onResume() {
        super.onResume();
        v.resume();
    }

    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    public void getScreenWidthAndHeight() {
        Point size = new Point();
        w = getWindowManager();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
            w.getDefaultDisplay().getSize(size);

            Measuredwidth = size.x;
            Measuredheight = size.y;
        } else {
            Display d = w.getDefaultDisplay();
            Measuredwidth = d.getWidth();
            Measuredheight = d.getHeight();

        }
    }
}

为了彻底,这里也是清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.something"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.something.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name="com.example.something.demosf"
            android:label="@string/app_name"
            android:screenOrientation="landscape"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            >
            <intent-filter>
                <action android:name="com.example.something.DEMO" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

    </application>

</manifest>

现在我似乎遇到的问题是,在我的 Nexus 7 上,这完全符合我的预期。然而,在我的朋友 Toshiba Thrive 上,图像的底部被底部的条截断了。这是比较: Nexus7 位于右侧,Thrive 位于左侧。所以我的问题是:到底发生了什么,我该如何解决这个问题? (最好适用于所有 Android 版本) 哦,附带问题:那个底栏到底叫什么?哈哈

编辑:我知道这不是最好的代码,我只是使用此代码来演示正在发生的事情,并且可能会为我的“getScreenWidthAndHeight()”方法找到一种不同的方法来解释设备中这种奇怪的重叠它发生在

【问题讨论】:

  • 它被称为系统栏,仅供参考。
  • 很高兴知道,非常感谢 =) 知道如何解释这一点吗?我在stackoverflow.com/questions/3407256/… 找到了一个“getStatusBarHeight()”方法,但是由于我的 Nexus 7 似乎没有考虑到那个栏,而繁荣确实如此,我仍然希望有人有某种解决方案
  • 状态栏和系统栏不是一回事;系统栏由(通常在底部)一组控件组成,这些控件在大多数设备上是/曾经是触摸按钮。状态栏是(通常在顶部)包含您的通知、电池寿命等的栏。

标签: android surfaceview


【解决方案1】:

代替:

c.drawBitmap(whatever, ((float) Measuredwidth - (float) whatever.getWidth()), 
          ((float) Measuredheight - (float) whatever.getHeight()), null);

使用:

c.drawBitmap(whatever, ((float) this.getWidth() - (float) whatever.getWidth()), 
          ((float) this.getHeight() - (float) whatever.getHeight()), null);

原因:

您定位位图的方法假定底部没有屏幕装饰。事实上,它根本不考虑装饰视图。您应该使用 Activity 视图的尺寸来处理定位。

编辑:

就您的活动而言,以下内容将为您提供视图的尺寸:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Measuredwidth = 0;
    Measuredheight = 0;
    getScreenWidthAndHeight();
    whatever = BitmapFactory.decodeResource(getResources(), R.raw.dragarrow);
    v = new OurView(this);

    v.post(new Runnable() {

        @Override
        public void run() {
            Measuredwidth = v.getWidth();
            Measuredheight = v.getHeight();    
        }
    });

    setContentView(v);
}

编辑 2:

LinearLayout llMain;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Measuredwidth = 0;
    Measuredheight = 0;
    //getScreenWidthAndHeight();
    whatever = BitmapFactory.decodeResource(getResources(), R.raw.dragarrow);

    llMain = new LinearLayout(this);

    setContentView(llMain);

    llMain.post(new Runnable() {

        @Override
        public void run() {

            Measuredwidth = llMain.getWidth();
            Measuredheight = llMain.getHeight();    

            scaleAndTrimImages();

            v = new OurView(demosf.this);

            llMain.addView(v);                
        }
    });

}

public void scaleAndTrimImages() {

    // Use Measuredwidth and Measuredheight
    // Since you are calling this method from onCreate(Bundle),
    // it runs only once.

}

【讨论】:

  • Ooo 看起来很有希望,我会试试看^_^
  • 那么我如何获得方法本身的大小呢?实际上,我需要在 onCreate 方法中发现这些测量值,与我的示例中使用 getScreenWidthAndHeight() 方法相同。您说使用设置为“v”的活动视图,但是当我使用 v.getWidth() 设置宽度时,我返回 0
  • @codingNewb 谢谢。定位子视图的可靠方法是使用父视图的边界矩形。创建一个Rect 变量:Rect r = new Rect();。获取父视图的边界:this.getGlobalVisibleRect(r);。现在,使用:c.drawBitmap(whatever, ((float) r.right - (float) whatever.getWidth()), ((float) r.bottom - (float) whatever.getHeight()), null);。祝你好运!
  • 我正在尝试使用“this.getGlobalVisibleRect(r);” onCreate 没有成功,这种方法在上面绘制位图的 run 方法中有效,但是我真的需要 onCreate 方法中的尺寸和“this.getGlobalVisibleRect(r);”那里似乎不起作用
  • 在解决了我自己的一些错误之后,终于能够在我的实际应用程序中实现它,我必须非常感谢你的所有帮助,你太棒了^_^
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-01
  • 1970-01-01
  • 2015-05-02
  • 1970-01-01
  • 1970-01-01
  • 2020-03-23
相关资源
最近更新 更多