ソフトウェアキーボードが表示されるたびに、背景画像のサイズが変更されます。以下のスクリーンショットを参照してください。
ご覧のとおり、背景は少し絞られています。誰でも背景のサイズが変更される理由を知ることができますか?
私のレイアウトは次のとおりです。
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:background="@drawable/page_bg"
Android:isScrollContainer="false"
>
<LinearLayout Android:layout_height="wrap_content"
Android:orientation="horizontal"
Android:layout_width="fill_parent"
>
<EditText Android:id="@+id/CatName"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:layout_weight="1"
Android:inputType="textCapSentences"
Android:lines="1"
/>
<Button Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="@string/save"
Android:onClick="saveCat"
/>
</LinearLayout>
<ImageButton
Android:id="@+id/add_totalk"
Android:layout_height="wrap_content"
Android:layout_width="wrap_content"
Android:background="@null"
Android:src="@drawable/add_small"
Android:scaleType="center"
Android:onClick="createToTalk"
Android:layout_marginTop="5dp"
/>
</LinearLayout>
OKを使用して修正しました
Android:windowSoftInputMode="stateVisible|adjustPan"
manifest
ファイルの<Activity >
タグ内のエントリ。アクティビティ内にScrollViewを持っていることが原因だと思います。
背景画像付きのチャットアプリ、チャット画面の開発中に、同じ問題に直面しました。 _Android:windowSoftInputMode="adjustResize"
_は、ソフトキーボードが表示され、ソフトキーボードを調整するために「adjustPan」がレイアウト全体をシフトした後、使用可能なスペースに合うように背景画像を圧縮しました。この問題の解決策は、アクティビティXML内にレイアウトの背景ではなくウィンドウの背景を設定することでした。アクティビティでgetWindow().setBackgroundDrawable()
を使用します。
この種の問題を回避するための最良の解決策は次のとおりです。
ステップ1:スタイルを作成する
<style name="ChatBackground" parent="AppBaseTheme">
<item name="Android:windowBackground">@drawable/bg_chat</item>
</style>
ステップ2:AndroidManifest
ファイルにアクティビティスタイルを設定します
<activity
Android:name=".Chat"
Android:screenOrientation="portrait"
Android:theme="@style/ChatBackground" >
Android:windowSoftInputMode = "adjustPan"を使用すると、画面全体が最上部に移動する(topにシフトする)ため、ユーザーエクスペリエンスが低下します。したがって、以下が最良の回答の1つです。
私は同じ問題を抱えていますが、その後、@ Gemからの素晴らしい答えを見つけました
マニフェスト内
Android:windowSoftInputMode="adjustResize|stateAlwaysHidden"
XMLで
ここに背景を設定せず、ScrollViewの下にビューを保持します
Javaの場合
背景をウィンドウに設定する必要があります。
getWindow().setBackgroundDrawableResource(R.drawable.bg_wood) ;
@Gemに感謝します。
加えて...
アクティビティのリストビューがある場合、リストビューのプロパティにこのAndroid:isScrollContainer="false"
を追加する必要があります...
アクティビティでマニフェストxmlにAndroid:windowSoftInputMode="adjustPan"
を追加することを忘れないでください...
レイアウトのスクロール可能なビューでAndroid:windowSoftInputMode="adjustUnspecified"
を使用している場合、ソフトキーボードによって背景のサイズが変更されます...
背景のサイズ変更を防ぐために「adjustPan」値を使用するとよいでしょう...
誰かがadjustResize
動作を必要とし、ImageView
のサイズを変更したくない場合は、別の回避策があります。
ImageView
の中にScrollView
を入れるだけで、ScrollView.fillViewport = true
でRelativeLayout
になります。
<ScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fillViewport="true">
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<FrameLayout
Android:layout_width="100dp"
Android:layout_height="100dp">
<ImageView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:scaleType="fitXY"
Android:src="@drawable/gift_checked" />
</FrameLayout>
</RelativeLayout>
</ScrollView>
アプリの作業中に主な問題が発生しました。最初に、@ parulbが提供するメソッドを使用して問題を解決します。彼に感謝します。しかし、後で、背景画像がアクションバー(およびステータスバー)によって部分的に非表示になっていることに気付きました。この小さな問題は@ zgc7009によって既に提案されており、1年半前に@parulbの回答の下でコメントしましたが、誰も返信しませんでした。
方法を見つけるために丸1日働きましたが、幸いなことに、少なくとも今は携帯電話でこの問題を完全に解決できます。
まず、背景画像の上部にパディングを追加するために、ドロアブルフォルダーにレイヤーリストリソースが必要です。
<!-- my_background.xml -->
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:top="75dp">
<bitmap Android:src="@drawable/bg" />
</item>
</layer-list>
次に、上記のようにこのファイルをバックグラウンドのリソースとして設定します。
getWindow().setBackgroundDrawableResource(R.drawable.my_background);
Nexus 5を使用しています。ステータスバーではなくxmlでアクションバーの高さを取得する方法を見つけたため、上部のパディングに固定高さ75dpを使用する必要があります。誰もがこのパズルの最後のピースを見つけられることを願っています。
AndroidManifest.xmlファイルに次の行を追加します。
Android:windowSoftInputMode=adjustUnspecified
詳細については このリンク を参照してください。
利用可能なすべての回答を調査および実装した後、ここでソリューションを追加しています。
この答えは、次のコードの組み合わせです。
https://stackoverflow.com/a/45620231/1164529
https://stackoverflow.com/a/27702210/1164529
これは、w.r.tで伸縮もスクロールもしなかったカスタムAppCompatImageView
クラスです。ソフトキーボード:-
public class TopCropImageView extends AppCompatImageView {
public TopCropImageView(Context context) {
super(context);
setScaleType(ImageView.ScaleType.MATRIX);
}
public TopCropImageView(Context context, AttributeSet attrs) {
super(context, attrs);
setScaleType(ImageView.ScaleType.MATRIX);
}
public TopCropImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setScaleType(ImageView.ScaleType.MATRIX);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
computeMatrix();
}
@Override
protected boolean setFrame(int l, int t, int r, int b) {
computeMatrix();
return super.setFrame(l, t, r, b);
}
private void computeMatrix() {
if (getDrawable() == null) return;
Matrix matrix = getImageMatrix();
float scaleFactor = getWidth() / (float) getDrawable().getIntrinsicWidth();
matrix.setScale(scaleFactor, scaleFactor, 0, 0);
setImageMatrix(matrix);
}
}
Fragment
クラスの背景として使用するには、最初の要素としてFrameLayout
に設定します。
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<complete.package.TopCropImageView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:src="@mipmap/my_app_background" />
<!-- Enter other UI elements here to overlay them on the background image -->
<FrameLayout>
onCreate()
でこのコードを使用するだけです:
protected void onCreate(Bundle savedInstanceState) {
...
getWindow().setBackgroundDrawableResource(R.drawable.your_image_resource);
...
}
xmlで次の行を削除します。
Android:background="@drawable/background"
続きを読む:
http://developer.Android.com/reference/Android/view/Window.html
おかげで: エイドリアン・シド・アルマグエル
背景画像がImageView
内のFragment
であり、キーボードでサイズ変更されたときに、この問題に直面しました。
私の解決策は: this SO Answer のカスタムImageView
を使用し、androidx
と互換性があるように編集しました。
import Android.content.Context;
import Android.graphics.Matrix;
import Android.util.AttributeSet;
import androidx.appcompat.widget.AppCompatImageView;
/**
* Created by chris on 7/27/16.
*/
public class TopCropImageView extends AppCompatImageView {
public TopCropImageView(Context context) {
super(context);
setScaleType(ScaleType.MATRIX);
}
public TopCropImageView(Context context, AttributeSet attrs) {
super(context, attrs);
setScaleType(ScaleType.MATRIX);
}
public TopCropImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setScaleType(ScaleType.MATRIX);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
recomputeImgMatrix();
}
@Override
protected boolean setFrame(int l, int t, int r, int b) {
recomputeImgMatrix();
return super.setFrame(l, t, r, b);
}
private void recomputeImgMatrix() {
if (getDrawable() == null) return;
final Matrix matrix = getImageMatrix();
float scale;
final int viewWidth = getWidth() - getPaddingLeft() - getPaddingRight();
final int viewHeight = getHeight() - getPaddingTop() - getPaddingBottom();
final int drawableWidth = getDrawable().getIntrinsicWidth();
final int drawableHeight = getDrawable().getIntrinsicHeight();
if (drawableWidth * viewHeight > drawableHeight * viewWidth) {
scale = (float) viewHeight / (float) drawableHeight;
} else {
scale = (float) viewWidth / (float) drawableWidth;
}
matrix.setScale(scale, scale);
setImageMatrix(matrix);
}
}
私は同様の問題に苦しんでいましたが、adjustPan
をAndroid:isScrollContainer="false"
で使用してもまだレイアウトが修正されなかったようです(これはLinearLayoutの下のRecyclerViewでした)。 RecyclerViewは問題ありませんでしたが、仮想キーボードが表示されるたびに、LinearLayoutが再調整されました。
この動作を防ぐために(キーボードをレイアウト上に配置したかっただけです)、次のコードを使用しました。
<activity
Android:name=".librarycartridge.MyLibraryActivity"
Android:windowSoftInputMode="adjustNothing" />
これはAndroid=に、仮想キーボードが呼び出されたときに基本的にレイアウトをそのままにするように伝えます。
考えられるオプションについての詳細は、 here を参照してください(奇妙なことに、adjustNothing
のエントリがあるようには見えません)。
以前にも同じ問題に直面していましたが、Fragment
を使用していたので長い間解決できませんでした。また、getActivity().getWindow().setBackgroundDrawable()
は私にとっては解決策ではありませんでした。
私のために働いた解決策は、表示されるはずのキーボードを処理し、外出先でビットマップを変更するロジックでFrameLayout
をオーバーライドすることです。
FrameLayoutコード(Kotlin)は次のとおりです。
_class FlexibleFrameLayout : FrameLayout {
var backgroundImage: Drawable? = null
set(bitmap) {
field = bitmap
invalidate()
}
private var keyboardHeight: Int = 0
private var isKbOpen = false
private var actualHeight = 0
constructor(context: Context) : super(context) {
init()
}
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) {
init()
}
fun init() {
setWillNotDraw(false)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val height = MeasureSpec.getSize(heightMeasureSpec)
if (actualHeight == 0) {
actualHeight = height
return
}
//kb detected
if (actualHeight - height > 100 && keyboardHeight == 0) {
keyboardHeight = actualHeight - height
isKbOpen = true
}
if (actualHeight - height < 50 && keyboardHeight != 0) {
isKbOpen = false
}
if (height != actualHeight) {
invalidate()
}
}
override fun onDraw(canvas: Canvas) {
if (backgroundImage != null) {
if (backgroundImage is ColorDrawable) {
backgroundImage!!.setBounds(0, 0, measuredWidth, measuredHeight)
backgroundImage!!.draw(canvas)
} else if (backgroundImage is BitmapDrawable) {
val scale = measuredWidth.toFloat() / backgroundImage!!.intrinsicWidth.toFloat()
val width = Math.ceil((backgroundImage!!.intrinsicWidth * scale).toDouble()).toInt()
val height = Math.ceil((backgroundImage!!.intrinsicHeight * scale).toDouble()).toInt()
val kb = if (isKbOpen) keyboardHeight else 0
backgroundImage!!.setBounds(0, 0, width, height)
backgroundImage!!.draw(canvas)
}
} else {
super.onDraw(canvas)
}
}
}
_
そして、通常のFrameLayoutの背景のように使用しました。
frameLayout.backgroundImage = Drawable.createFromPath(path)
それが役に立てば幸い。
LinearLayoutをFrameLayoutでラップし、ImageViewを背景で追加できます。
<FrameLayout>
<ImageView
Android:background="@drawable/page_bg"
Android:id="@+id/backgroundImage" />
<LinearLayout>
....
</LinearLayout>
</FrameLayout>
また、アクティビティ/フラグメントを作成するときに高さを設定できます(キーボードを開いたときにスケーリングしないようにするため)。フラグメントのKotlinのコード:
activity?.window?.decorView?.height?.let {
backgroundImage.setHeight(it)
}
アクティビティを追加するだけです
getWindow().setBackgroundDrawable(R.drawable.your_image_name);
ウィンドウの背景として画像を設定し、uiがスタックする場合。単一のドロウアブルフォルダーにあるドロウアブルを使用している可能性があります。はいの場合、drawable-nodpiまたはdrawable-xxxhdpiに貼り付ける必要があります。