私はimageviewを持っています。幅をfill_parentにしたい。私はその高さが幅が最終的に何であれ何であれ欲しいです。例えば:
<ImageView
android:layout_width="fill_parent"
android:layout_height="whatever the width ends up being" />
独自のビュークラスを作成しなくても、レイアウトファイルでそのようなことが可能ですか?
ありがとう
私はimageviewを持っています。幅をfill_parentにしたい。私はその高さが幅が最終的に何であれ何であれ欲しいです。例えば:
<ImageView
android:layout_width="fill_parent"
android:layout_height="whatever the width ends up being" />
独自のビュークラスを作成しなくても、レイアウトファイルでそのようなことが可能ですか?
ありがとう
回答:
更新:2017年9月14日
以下のコメントによると、パーセントサポートライブラリはAndroidサポートライブラリ26.0.0で廃止されています。これは、新しい方法です。
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1" />
</android.support.constraint.ConstraintLayout>
こちらをご覧ください
非推奨:
Android Developersによるこの投稿によると、PercentRelativeLayoutまたはPercentFrameLayout内で必要なものをラップし、その比率を指定するだけです。
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
app:layout_widthPercent="100%"
app:layout_aspectRatio="100%"/>
</android.support.percent.PercentRelativeLayout>
多分これはあなたの質問に答えます:
<ImageView
android:id="@+id/cover_image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:adjustViewBounds="true" />
scaleTypeこの特定の状況では、属性を無視できます。
実行時にビューの幅がわかったら、LayoutParamsを使用してビューの高さを動的に設定できます。実行時にビューの幅を取得するには、Runnableスレッドを使用する必要があります。そうしないと、レイアウトがまだ描画されていないため、ビューの幅がわかる前に高さを設定しようとします。
問題の解決方法の例:
final FrameLayout mFrame = (FrameLayout) findViewById(R.id.frame_id);
mFrame.post(new Runnable() {
@Override
public void run() {
RelativeLayout.LayoutParams mParams;
mParams = (RelativeLayout.LayoutParams) mFrame.getLayoutParams();
mParams.height = mFrame.getWidth();
mFrame.setLayoutParams(mParams);
mFrame.postInvalidate();
}
});
LayoutParamsは、ビューが含まれている親ビューのタイプである必要があります。私のFrameLayoutは、xmlファイルのRelativeLayout内にあります。
mFrame.postInvalidate();
UIスレッドとは別のスレッドでビューを強制的に再描画するために呼び出されます
onMeasure示されているように、解決が可能な最も早い瞬間は、カスタム中です。別の方法ですが、内部など、アダプターを介してレンダリングされるビューのみがMattの答えです。GridView
requestLayout()パラメータを設定した後に呼び出した後でのみうまくいきました。なぜでしょうか?
私は、David Chuの回答をRecyclerViewアイテムに対して機能させることができず、ImageViewを親に制限する必要があることがわかりました。ImageViewの幅をに設定し、0dpその開始と終了を親に制限します。幅をに設定しwrap_contentたりmatch_parent、場合によっては機能したりするかどうかはわかりませんが、これは、ConstraintLayoutの子に親を設定させるためのより良い方法だと思います。
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintDimensionRatio="1:1"/>
</android.support.constraint.ConstraintLayout>
ここで私は常に幅が高さに等しいImageButtonを持つために何をしましたか(そして、一方向の愚かな空のマージンを避けます...これはSDKのバグと考えています...):
ImageButtonから拡張するSquareImageButtonクラスを定義しました。
package com.myproject;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageButton;
public class SquareImageButton extends ImageButton {
public SquareImageButton(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public SquareImageButton(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public SquareImageButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
int squareDim = 1000000000;
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int h = this.getMeasuredHeight();
int w = this.getMeasuredWidth();
int curSquareDim = Math.min(w, h);
// Inside a viewholder or other grid element,
// with dynamically added content that is not in the XML,
// height may be 0.
// In that case, use the other dimension.
if (curSquareDim == 0)
curSquareDim = Math.max(w, h);
if(curSquareDim < squareDim)
{
squareDim = curSquareDim;
}
Log.d("MyApp", "h "+h+"w "+w+"squareDim "+squareDim);
setMeasuredDimension(squareDim, squareDim);
}
}
これが私のxmlです:
<com.myproject.SquareImageButton
android:id="@+id/speakButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:src="@drawable/icon_rounded_no_shadow_144px"
android:background="#00ff00"
android:layout_alignTop="@+id/searchEditText"
android:layout_alignBottom="@+id/searchEditText"
android:layout_alignParentLeft="true"
/>
魅力的な作品!
Android 26.0.0では、PercentRelativeLayoutは非推奨になりました。
それを解決する最良の方法は、次のようにすることですConstraintLayout:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView android:layout_width="match_parent"
android:layout_height="0dp"
android:scaleType="centerCrop"
android:src="@drawable/you_image"
app:layout_constraintDimensionRatio="1:1"/>
</android.support.constraint.ConstraintLayout>
これは、プロジェクトに追加する方法に関するチュートリアルConstraintLayoutです。
レイアウトだけではできません。それを処理するための非常に単純なクラスを作成してしまいました。githubで確認できます。SquareImage.java大きなプロジェクトの一部ですが、コピーアンドペーストで修正できないものはありません(Apache 2.0でライセンスされています)
基本的に、高さ/幅を他の寸法に等しく設定する必要があります(スケーリングする方法によって異なります)。
注:scaleType属性を使用してカスタムクラスなしで正方形にすることもできますが、ビューの境界が表示されている画像を超えているため、近くに他のビューを配置すると問題になります。
ImageViewを画面の半分に設定するには、ImageViewのXMLに以下を追加する必要があります。
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:scaleType="fitXY"
android:adjustViewBounds="true"/>
次に、高さをこの幅に等しく設定するには、コードでそれを行う必要があります。アダプターのgetViewメソッドでGridView、ImageView高さを測定された幅に等しく設定します。
mImageView.getLayoutParams().height = mImageView.getMeasuredWidth();
今を通り過ぎる人のために、2017年に、あなたが望むものを達成するための新しい最善の方法は、次のようにConstraintLayoutを使用することです:
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="1:1" />
また、レイアウトの必要に応じて、4つの方向すべてに制約を追加することを忘れないでください。
ConstraintLayoutでレスポンシブUIを構築する
さらに、現在では、PercentRelativeLayoutは非推奨になっています(Androidのドキュメントを参照)。
これが私がその問題をどのように解決したかです:
int pHeight = picture.getHeight();
int pWidth = picture.getWidth();
int vWidth = preview.getWidth();
preview.getLayoutParams().height = (int)(vWidth*((double)pHeight/pWidth));
プレビュー-幅が「match_parent」に設定され、scaleTypeが「cropCenter」に設定されたimageView
picture-imageView srcで設定するビットマップオブジェクト。
それは私にはかなりうまくいきます。
= vw*ph/pw、単純なものではなく、なぜ行うのかについても説明していません= vw。(正方形のプレビューを強制するのではなく、ソース画像のアスペクト比を維持するためにこれを行うと思います。)
ImageViewの「scaleType」関数は、ここで役立ちます。
このコードは、アスペクト比を維持し、画像を上部に配置します。
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitStart"
これは、scaleTypeを使用することの可能性と外観を示す素晴らしい投稿です。