8

Mind theRobotから入手できるAnalogGaugeサンプルコードに似た、Androidアプリケーションのカスタムビューに取り組んでいます。

リストされたサイトからコードを実行すると、画面に次のように表示されます。

(Motorola Droid、2.2.3)、(エミュレーター、4.0.3)

矢印があります

(Xoom、4.0.3)(その他の電話、4.0.3)

矢印がありません

手がありません!

描画呼び出しが行われていますが(logcatで確認できます)、呼び出しが描画するキャンバス要素は表示されません。

ただし、 APIレベルには依存しません。プロジェクトに正しい方法でインポートすると、Xoomで実行したときに手が表示されます。

しかし、ファイルを別のプロジェクトフォルダー(同じソースコード、同じレイアウト)に移動すると、ダイヤルが表示されなくなります。

どうしたの?同じコードが異なるデバイスでこのような異なる結果をどのように生み出しているのでしょうか?

4

6 に答える 6

13

それで、私の謎の重要な手がかりは、それがエミュレーターでは機能したが、ハードウェアデバイスでは機能しなかったということのようでした。

ハードウェアレンダリング

Android開発者のWebサイトのハードウェアレンダリングページを熟読しましたが、明らかに十分ではありません。

http://developer.android.com/guide/topics/graphics/hardware-accel.html

APIはバージョン11以降で利用可能であると記載されていますが、APIレベル14(ICS)以降、すべてのアプリケーションでハードウェアレンダリングがデフォルトでオンになっているとは言えません。

これは私たちにとってどういう意味ですか?

ほとんどすべてが高速です。動作しないいくつかのことを除いて。

私は気づかずに、これらのうちの2つに違反することに成功しました。

  • Canvas.DrawTextOnPath()
  • Paint.setShadowLayer()

APIリファレンス(または私が見つけることができる他の場所、そして確かにLintによってチェックされていない場所)には記載されていませんが、リストされている操作のいずれかを使用すると、奇妙なことができます。

私の場合、Canvas.DrawTextOnPath()は問題なく機能しているように見えました。

しかし、Androidは、私が手に使用したペイントにシャドウレイヤーが設定されていることに気付いたとき、それを黙って無視しました。

ビューがハードウェアアクセラレーションされているかどうかはどうすればわかりますか?

上記のドキュメントリンクから:

アプリケーションがハードウェアアクセラレーションされているかどうかを確認するには、次の2つの方法があります。

  • View.isHardwareAccelerated()は、ビューがハードウェアアクセラレーションウィンドウに接続されている場合にtrueを返します。
  • Canvasがハードウェアアクセラレーションされている場合、Canvas.isHardwareAccelerated()はtrueを返します

図面コードでこのチェックを行う必要がある場合は、可能であれば、View.isHardwareAccelerated()の代わりにCanvas.isHardwareAccelerated()を使用してください。ビューがハードウェアアクセラレーションウィンドウにアタッチされている場合でも、ハードウェア以外のアクセラレーションキャンバスを使用して描画できます。これは、たとえば、キャッシュの目的でビューをビットマップに描画するときに発生します。

私の場合、逆のことが起こったようです。カスタムビューは、ハードウェアアクセラレーションではないことをログに記録します。ただし、キャンバスはハードウェアアクセラレーションであると報告します。

回避策と修正

最も簡単な修正は、カスタムビューにソフトウェアレンダリングを強制することです。ドキュメントによると、これは次の方法で実行できます。

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

または、問題のある操作を削除して、ハードウェアレンダリングをオンのままにしておくこともできます。

私の不幸から学びなさい。頑張ってください。

于 2012-07-12T21:27:59.727 に答える
3

私はそれをinit()に入れ、その後うまくいきました。

    private void init() {
    setLayerType(myView.LAYER_TYPE_SOFTWARE, null);
    ....
}
于 2013-12-08T20:51:39.653 に答える
2

myView.setLayerType(View.LAYER_TYPE_SOFTWARE、null);を使用します。手が見える提案。しかし、まだ問題があります。0しか書かれていないスケールが表示されます。写真のように、スキーマから2つの階層ゼロがあります:(GALAXY NEXUS 4.2.1)

ここに画像の説明を入力してください

私のdrawScale()メソッドは次の例のようになります。

 private void drawScale(Canvas canvas) {
        canvas.drawOval(scaleRect, scalePaint);

        canvas.save(Canvas.MATRIX_SAVE_FLAG);
        for (int i = 0; i < totalNicks; ++i) {
            float y1 = scaleRect.top;
            float y2 = y1 - 0.020f;

            canvas.drawLine(0.5f, y1, 0.5f, y2, scalePaint);


            if ((i % 5) == 0) {
                int value = nickToDegree(i);

                if ((value >= minDegrees) && (value <= maxDegrees)) {
                    String valueString = Integer.toString(value);
                    canvas.drawText(valueString, 0.5f, y2 - 0.015f, scalePaint);

                }
            }

            canvas.rotate(degreesPerNick, 0.5f, 0.5f);


        }
        canvas.restore();

    }
于 2014-10-19T14:04:18.527 に答える
0

私の場合、私はこれを作りました:

 AnalogView bar = (AnalogView) findViewById(R.id.AnalogBar);
    bar.setLayerType(bar.LAYER_TYPE_SOFTWARE, null);
if (value_list.size()>0)   bar.SetData(Double.parseDouble(value_list.get(value_list.size()-1)));

AnalogViewのSetDataは

public  void SetData(double data) {
    setHandTarget((float)data);
  invalidate();
}
于 2014-05-01T14:33:19.150 に答える
0

Galaxy S4Android4.4.2の場合

TYPE_TEMPERATURE非推奨です

使用する

TYPE_AMBIENT_TEMPERATURE

于 2014-06-07T17:25:07.797 に答える
-1

初期化での縮尺でのテキストの描画に問題がある場合は、次のようにします。

scalePaint.setLinearText(true);

于 2014-12-27T18:12:37.817 に答える