2017-02-14 16 views
7

mam prosty widok:marże android nie działa, gdy dynamicznie wstawiać widoki

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:background="@drawable/contact_selected" 
    android:layout_marginTop="10dp" 
    android:layout_marginEnd="5dp" 
    android:orientation="horizontal" 
    android:padding="3dp"> 
    <TextView 
     android:id="@+id/txt_title" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Billy Bob" 
     /> 
</LinearLayout> 

Kiedy statycznie skopiuj znaczników LinearLayout do mojego głównego układu działalności, marginesy są zgodnie z oczekiwaniami. Jednak po dynamicznym dodaniu widoku do głównego schematu działania marginesy są ignorowane. Oto jak wstawić pogląd

LayoutInflater inflater = (LayoutInflater) 
     getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
View view = inflater.inflate(R.layout.test, null); 
TextView txt_title = (TextView)view.findViewById(R.id.txt_title); 
txt_title.setText("DynamiC#1"); 
llayout.addView(view, llayout.getChildCount()-1); 

View view2 = inflater.inflate(R.layout.test, null); 
txt_title = (TextView)view2.findViewById(R.id.txt_title); 
txt_title.setText("DynamiC#2"); 
llayout.addView(view2, llayout.getChildCount()-1); 

Oto jak to wygląda:

enter image description here

Pojemnik w głównym układzie jest LinearLayout, który jest dzieckiem HorizontalScrollView. Wszelkie docenienia jest doceniane.

Odpowiedz

14

Podczas dynamicznego dodawania widoków nie należy nadużywać jednostki nadrzędnej z jednostką macierzystą null . Innymi słowy, powinieneś używać inflater.inflate(R.layout.test, linearLayout, false);. Element nadrzędny jest używany podczas określania typu parametrów układu do wygenerowania. Przekaż kontener nadrzędny (w tym przypadku układ liniowy), aby poprawnie utworzyć instancję ViewGroup.MarginLayoutParams z pliku XML.

+0

Dzięki, to jest czyste rozwiązanie i jest moim preferowanym sposobem na to. Dla każdego, kto uczy się tego, zwróć uwagę, że ponieważ inflate (view, parent) nadyma widok do rodzica (dodaje się jako ostatnie dziecko), wiersz w kodzie testowym, do którego dodaję widok (np. Llayout.addView()) spowoduje błąd, ponieważ widok został już wstawiony. W moim przypadku muszę zachować stały widok jako ostatnie dziecko i wstawić przed nim nowe dzieci. Dlatego usunąłem mój ostatni widok przed nadmuchaniem() i dodałem go ponownie po nadmuchaniu(). Działa jak marzenie. –

+0

@JohnWard faktycznie nadal potrzebujesz addView, jeśli użyjesz "inflater.inflate (R.layout.test, linearLayout, false)" z tym ostatnim parametrem boolowskim. – Flyview

2

Dzieje się tak, ponieważ trzeba dynamicznie nadawać układom "Margin". Można to zrobić przez utworzenie obiektu "LayoutPrams", tak: -

LinearLayout ll = new LinearLayout(this); 
ll.setOrientation(LinearLayout.VERTICAL); 

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); 
layoutParams.setMargins(30, 20, 30, 0); 

Tutaj można ustawić LayoutParams do linearlayout:

ll.addView(okButton, layoutParams); 

Nadzieję, że to pomaga.

+0

Dziękuję. Kolejna tajemnica Androida rozwiązana! –

+0

Przykro mi, ale zmieniam zatwierdzoną odpowiedź na odpowiedź oferowaną przez Submersed. Twoja odpowiedź była przydatna i nauczyła mnie czegoś, czego nie wiedziałam, ale jego odpowiedź jest czystsza i nie zmusza mnie do obniżania wartości na marginesie. Dzięki jeszcze raz. –

+0

Dzięki za twoją opinię John. –

0

Najpierw musisz uzyskać gęstość wyświetlania. powiązane dokumenty to: https://developer.android.com/reference/android/util/DisplayMetrics.html

oraz identyfikator, który ma zostać ustawiony jako widok marginesów. za moim przypadku

layout_login_box = (ConstraintLayout)findViewById(R.id.login_layout_box); 

float density = getResources().getDisplayMetrics().density; 

ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams)layout_login_box.getLayoutParams(); 
params.setMargins((int) (24 * density),0,(int) (24 * density),(int) (16 * density)); 
layout_login_box.setLayoutParams(params); 

Ponadto, można zmienić ConstraintLayout do własnego widzenia.

Powiązane problemy