web-dev-qa-db-ja.com

ImageView scaleType 'centerCrop'と同等のビットマップ描画可能重力

ヘッダー画像のあるアクティビティを作成しました。このヘッダー画像は、scaleTypeがcenterCropに設定されているImageViewを使用して、アクティビティのレイアウトxmlで最初に作成されました。これは私が望むことを行います、それは画像を中央に配置し、縦向きモードで左右に切り取り、すべて横向きモードで表示します。

<LinearLayout 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"
    Android:paddingTop="30dp"
    Android:paddingBottom="6dp"
    Android:paddingLeft="6dp"
    Android:paddingRight="6dp"
    Android:background="#919EAC"
    Android:orientation="vertical" >

<ImageView
    Android:id="@+id/header_image"
    Android:layout_width="match_parent"
    Android:layout_height="120dp"
    Android:contentDescription="@string/header_description"
    Android:scaleType="centerCrop"
    Android:src="@drawable/header" />

    .... <other views> ...

これを背景のドローアブルに置き換えて、ヘッダー画像スペースを使用してデータを表示できるようにします。これにより、さまざまなアクティビティで同じレイアウトを繰り返す必要がなくなります。

このため、Android:background属性で参照できるドローアブルを作成しました。

    <layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
        <item>
            <shape Android:shape="rectangle" >
                <solid Android:color="#919EAC" />
            </shape>
        </item>
        <item>
            <bitmap 
                Android:antialias="true"
                Android:gravity="top|center_horizontal"
                Android:src="@drawable/header" />
        </item>
    </layer-list>

このドローアブルは、そうでなければレイアウトで定義される色付きの背景を定義し、そうでなければレイアウトにImageViewとして含まれるヘッダー画像を定義します。

しかし、今、私の画像は拡大縮小されていますが、トリミングしたいのですが。

Androidのドキュメントを確認しました。

    Android:gravity="top|clip_horizontal"

しかし、それでも画像ビューとは異なる方法で表示/スケーリングされているようです。

背景ドローアブルの正しい定義は何でしょうか?

38
M. le Rutte

基になるドローアブルのアスペクト比を維持するデコレーターでこの問題を解決しました: https://Gist.github.com/rudchenkos/e33dc0d6669a61dde9d6548f6c3e0e7e

残念ながら、XMLから適用する方法はないので、スプラッシュアクティビティの最初にそれを行います。

public class SplashActivity extends AppCompatActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final Drawable bg = getResources().getDrawable(R.drawable.screen);
        getWindow().setBackgroundDrawable(new CenterCropDrawable(bg));

        ...
    }
}

これは、アクティビティテーマでドローアブルをAndroid:windowBackgroundとして指定することとほぼ同じです。

3

コードでビットマップを中央にトリミングするには、次の操作を行います。

public static Bitmap cropCenter(Bitmap bmp) {
    int dimension = Math.min(bmp.getWidth(), bmp.getHeight());
    return ThumbnailUtils.extractThumbnail(bmp, dimension, dimension);
}

ビットマップのxmlを賢くCenterCropする他の方法は知りません。

それが誰にも役立つことを願っています。

私はこの投稿からこの解決策を見つけました: ビットマップのAndroidクロップセンター

2
Arnold Balliu

バックグラウンドでそれを行う方法がわかりません。ただし、他の解決策を試すこともできます。

1)画像の上に何かを表示するための最も簡単な解決策は、それらを重ねて配置することです。たとえば、ImageViewの次元でRelativeLayoutを使用できます。ImageViewは、両方の次元でmatch_parentであり、中央にTextViewです。

2)Imageviewを別のレイアウト(header.xmlなど)で保存し、include header.xmlを使用して必要な場所で使用できます。

3)ImageViewの上に表示されるレイアウトがどこでも同じである場合は、ImageViewを使用してカスタムレイアウトを作成し、たとえばTextViewを中央に配置して、そのレイアウトをどこでも使用できます。次に、このカスタムレイアウトにTextView文字列を設定できます。カスタムレイアウトについて詳しく読むことができます。それらは簡単です。

0
Raghubansh Mani