Kann dieses Attribut in Java-Code dynamisch geändert werden?
android:layout_marginRight
Ich habe eine TextView
, die ihre Position einige Pixel nach links dynamisch ändern muss.
Wie geht das programmgesteuert?
Kann dieses Attribut in Java-Code dynamisch geändert werden?
android:layout_marginRight
Ich habe eine TextView
, die ihre Position einige Pixel nach links dynamisch ändern muss.
Wie geht das programmgesteuert?
Antworten:
BEARBEITEN: Eine allgemeinere Methode, die nicht vom Layouttyp abhängt (außer dass es sich um einen Layouttyp handelt, der Ränder unterstützt):
public static void setMargins (View v, int l, int t, int r, int b) {
if (v.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
p.setMargins(l, t, r, b);
v.requestLayout();
}
}
Sie sollten die Dokumente auf TextView überprüfen . Grundsätzlich möchten Sie das LayoutParams-Objekt von TextView abrufen, die Ränder ändern und dann wieder auf TextView zurücksetzen. Angenommen, es befindet sich in einem LinearLayout, versuchen Sie Folgendes:
TextView tv = (TextView)findViewById(R.id.my_text_view);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)tv.getLayoutParams();
params.setMargins(0, 0, 10, 0); //substitute parameters for left, top, right, bottom
tv.setLayoutParams(params);
Ich kann es momentan nicht testen, daher ist mein Casting möglicherweise etwas verschoben, aber die LayoutParams müssen geändert werden, um den Rand zu ändern.
Vergessen Sie nicht, dass Sie, wenn sich Ihre Textansicht beispielsweise in einem RelativeLayout befindet , RelativeLayout.LayoutParams anstelle von LinearLayout.LayoutParams verwenden sollten
Verwenden Sie LayoutParams (wie bereits erläutert). Achten Sie jedoch darauf, welche LayoutParams Sie auswählen. Laut https://stackoverflow.com/a/11971553/3184778 "müssen Sie diejenige verwenden, die sich auf das ELTERN der Ansicht bezieht, an der Sie arbeiten, nicht die tatsächliche Ansicht."
Befindet sich die Textansicht beispielsweise in einer TableRow, müssen Sie TableRow.LayoutParams anstelle von RelativeLayout oder LinearLayout verwenden
Verwenden Sie diese Funktion, um alle Randtypen festzulegen
public void setViewMargins(Context con, ViewGroup.LayoutParams params,
int left, int top , int right, int bottom, View view) {
final float scale = con.getResources().getDisplayMetrics().density;
// convert the DP into pixel
int pixel_left = (int) (left * scale + 0.5f);
int pixel_top = (int) (top * scale + 0.5f);
int pixel_right = (int) (right * scale + 0.5f);
int pixel_bottom = (int) (bottom * scale + 0.5f);
ViewGroup.MarginLayoutParams s = (ViewGroup.MarginLayoutParams) params;
s.setMargins(pixel_left, pixel_top, pixel_right, pixel_bottom);
view.setLayoutParams(params);
}
Das Core KTX-Modul bietet Erweiterungen für allgemeine Bibliotheken, die unter anderem Teil des Android-Frameworks sind androidx.core.view
.
dependencies {
implementation "androidx.core:core-ktx:{latest-version}"
}
Die folgenden Erweiterungsfunktionen sind praktisch, um mit Rändern umzugehen:
setMargins()
Erweiterungsfunktion:Legt die Ränder aller Achsen in den ViewGroup
's fest MarginLayoutParams
. (Die Bemaßung muss in Pixel angegeben werden. Weitere Informationen finden Sie im letzten Abschnitt, wenn Sie mit dp arbeiten möchten.)
inline fun MarginLayoutParams.setMargins(@Px size: Int): Unit
// E.g. 16px margins
val params = (myView.layoutParams as ViewGroup.MarginLayoutParams)
params.setMargins(16)
updateMargins()
Erweiterungsfunktion:Aktualisiert die Ränder in den ViewGroup
's ViewGroup.MarginLayoutParams
.
inline fun MarginLayoutParams.updateMargins(
@Px left: Int = leftMargin,
@Px top: Int = topMargin,
@Px right: Int = rightMargin,
@Px bottom: Int = bottomMargin
): Unit
// Example: 8px left margin
params.updateMargins(left = 8)
updateMarginsRelative()
Erweiterungsfunktion:Aktualisiert die relativen Ränder in den ViewGroup
's MarginLayoutParams
(Start / Ende statt links / rechts).
inline fun MarginLayoutParams.updateMarginsRelative(
@Px start: Int = marginStart,
@Px top: Int = topMargin,
@Px end: Int = marginEnd,
@Px bottom: Int = bottomMargin
): Unit
// E.g: 8px start margin
params.updateMargins(start = 8)
Die folgenden Erweiterungseigenschaften sind praktisch, um die aktuellen Ränder abzurufen:
inline val View.marginBottom: Int
inline val View.marginEnd: Int
inline val View.marginLeft: Int
inline val View.marginRight: Int
inline val View.marginStart: Int
inline val View.marginTop: Int
// E.g: get margin bottom
val bottomPx = myView1.marginBottom
dp
statt px
:Wenn Sie dp
stattdessen mit (dichteunabhängigen Pixeln) arbeiten möchten px
, müssen Sie diese zuerst konvertieren. Mit der folgenden Erweiterungseigenschaft können Sie dies problemlos tun:
val Int.px: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
Dann können Sie die vorherigen Erweiterungsfunktionen wie folgt aufrufen:
params.updateMargins(start = 16.px, end = 16.px, top = 8.px, bottom = 8.px)
val bottomDp = myView1.marginBottom.dp
Alte Antwort:
In Kotlin können Sie eine Erweiterungsfunktion wie folgt deklarieren:
fun View.setMargins(
leftMarginDp: Int? = null,
topMarginDp: Int? = null,
rightMarginDp: Int? = null,
bottomMarginDp: Int? = null
) {
if (layoutParams is ViewGroup.MarginLayoutParams) {
val params = layoutParams as ViewGroup.MarginLayoutParams
leftMarginDp?.run { params.leftMargin = this.dpToPx(context) }
topMarginDp?.run { params.topMargin = this.dpToPx(context) }
rightMarginDp?.run { params.rightMargin = this.dpToPx(context) }
bottomMarginDp?.run { params.bottomMargin = this.dpToPx(context) }
requestLayout()
}
}
fun Int.dpToPx(context: Context): Int {
val metrics = context.resources.displayMetrics
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), metrics).toInt()
}
Dann können Sie es so nennen:
myView1.setMargins(8, 16, 34, 42)
Oder:
myView2.setMargins(topMarginDp = 8)