Ustawianie marginesów w LinearLayout programowo

Próbuję użyć Javy (, a nie XML) do stworzenia LinearLayout z przyciskami wypełniającymi ekran i zawierającymi marginesy. Oto kod, który działa bez marginesów:

LinearLayout buttonsView = new LinearLayout(this);
buttonsView.setOrientation(LinearLayout.VERTICAL);
for (int r = 0; r < 6; ++r) {
    Button btn = new Button(this);
    btn.setText("A");

    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); // Verbose!
    lp.weight = 1.0f; // This is critical. Doesn't work without it.
    buttonsView.addView(btn, lp);
}

ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
setContentView(buttonsView, lp);

Więc to działa dobrze, ale jak na Boga dać przyciski marginesy tak, że jest przestrzeń między nimi? Próbowałem użyć LinearLayout.MarginLayoutParams, ale to nie ma weight członka, więc nie jest dobre. I nie działa, jeśli przekażesz go lp w jego konstruktorze.

Czy to niemożliwe? Bo na pewno tak wygląda, a nie Bądź pierwszym zadaniem układu Android, które można wykonać tylko w XML.
Author: Ziem, 0000-00-00

10 answers

Oto mały kod do wykonania:

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);

Button okButton=new Button(this);
okButton.setText("some text");
ll.addView(okButton, layoutParams);
 457
Author: Mauro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-06 18:57:59
Więc to działa dobrze, ale jak na ziemi czy podajesz marginesy przycisków tak jest między nimi przestrzeń?

Wywołujesz {[0] } Na obiekcie LinearLayout.LayoutParams.

Próbowałem użyć LinearLayout.MarginLayoutParams, ale który nie ma wagi więc nie dobrze.

LinearLayout.LayoutParams jest podklasą LinearLayout.MarginLayoutParams, Jak wskazano w dokumentacji .

Czy to niemożliwe?
Nie.
To nie byłby pierwszy Android zadanie układu można wykonać tylko w XML

Możesz przedstawić dowód tego twierdzenia.

Osobiście nie jestem świadomy niczego, co można osiągnąć tylko za pomocą XML, a nie za pomocą metod Java w SDK. W rzeczywistości, z definicji, wszystko musi być wykonalne za pomocą Javy (choć niekoniecznie za pomocą SDK-reachable methods), ponieważ XML nie jest kodem wykonywalnym. Ale, jeśli jesteś świadomy czegoś, wskaż to, ponieważ jest to błąd w SDK, który powinien zostać kiedyś naprawiony.

 62
Author: CommonsWare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-20 01:22:44

Aby dodać marginesy bezpośrednio do elementów (niektóre elementy umożliwiają bezpośrednią edycję marginesów), możesz zrobić:

LayoutParams lp = ((ViewGroup) something).getLayoutParams();
if( lp instanceof MarginLayoutParams )
{
    ((MarginLayoutParams) lp).topMargin = ...;
    ((MarginLayoutParams) lp).leftMargin = ...;
    //... etc
}
else
    Log.e("MyApp", "Attempted to set the margins on a class that doesn't support margins: "+something.getClass().getName() );

...działa to bez potrzeby poznania / edycji otaczającego układu. Zwróć uwagę na opcję "instanceof", jeśli spróbujesz uruchomić to z czymś, co nie obsługuje marginesów.

 30
Author: Adam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-09 11:23:58

Ze względu na zmienność gęstości pikseli ekranu urządzenia dobrze jest zawsze używać jednostki DIP do programowego ustawiania marginesu. Jak below_

//get resources
Resources r = getResources();
float pxLeftMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxTopMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxRightMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxBottomMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());

//get layout params...
LayoutParams params=new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.setMargins(Math.round(pxLeftMargin), Math.round(pxTopMargin), Math.round(pxRightMargin), Math.round(pxBottomMargin));

//set margin...
yourLayoutTOsetMargin.setLayoutParams(params); 
Mam nadzieję, że to pomoże.
 19
Author: Rupesh Yadav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-09 13:25:31

Ustawiłem marginesy bezpośrednio za pomocą poniższego kodu

LinearLayout layout = (LinearLayout)findViewById(R.id.yourrelative_layout);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);            
params.setMargins(3, 300, 3, 3); 
layout.setLayoutParams(params);

Wystarczy zauważyć, że {[1] } należy zaimportować dla następującego pakietu android.widget.RelativeLayout.LayoutParams, w przeciwnym razie pojawi się błąd.

 8
Author: Janith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-17 08:21:19

Spróbuj tego

 LayoutParams params = new LayoutParams(
            LayoutParams.WRAP_CONTENT,      
            LayoutParams.WRAP_CONTENT
    );
    params.setMargins(left, top, right, bottom);
    yourbutton.setLayoutParams(params);
 7
Author: Karan Bhalodiya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-07 09:35:01
 MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();
 layoutParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
 7
Author: Ginni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-20 01:53:11
/*
 * invalid margin
 */
private void invalidMarginBottom() {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) frameLayoutContent.getLayoutParams();
    lp.setMargins(0, 0, 0, 0);
    frameLayoutContent.setLayoutParams(lp);
}

Powinieneś być ware rodzaju widoku viewGroup.In powyższy kod, na przykład, Chcę zmienić margines FrameLayout, a grupa widoku FrameLayout jest RelativeLayout , więc musisz ukryć (RelativeLayout.LayoutParams)

 3
Author: Francis Shi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-06 09:14:40

Spróbuj tego:

MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
params.width = 250;
params.leftMargin = 50;
params.topMargin = 50;
 2
Author: Makvin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-26 05:07:19

Tutaj jednolinijkowe Rozwiązanie:

((LinearLayout.LayoutParams) yourLinearLayout.getLayoutParams()).marginToAdd = ((int)(Resources.getSystem().getDisplayMetrics().density * yourDPValue));
 0
Author: Stappo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-19 11:00:23