Динамическая установка представлений с параметром LayoutParams.addRule на последнюю позицию представления

Я динамически добавляю представления в относительный макет и программно определяю их. Представления можно перемещать по экрану, чтобы их положение менялось.

Когда я пытаюсь установить представление (button2), чтобы сидеть ниже другого представления (button1), button2 помещается в старое местоположение кнопки 1 (по умолчанию местоположение, где представления добавляются до перемещения). Я связал изображения, чтобы надеяться передать это лучше.

Это макет оригинала Оригинальный макет

Макет после Button2 переустановлен Перестановка макета

У меня есть ссылка LinkedList, отслеживающая все изменения вида и атрибуты представления для макета, если это имеет значение.

Вот функции кода:

Как я переопределяю Button1:

Buttons b = (Buttons) viewIndex; positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams()); positioningLayout.addRule(RelativeLayout.CENTER_VERTICAL); b.setLayoutParams(positioningLayout); baseLayout.addView(b); 

Перемещение представлений под другим видом фрагмента кода:

 Buttons b = (Buttons) viewIndex; positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams()); positioningLayout.addRule(RelativeLayout.BELOW, viewIdFromList.intValue()); b.setLayoutParams(positioningLayout); b.invalidate(); 

Как я добавляю представления к макету.

 uiList.addView(new Buttons(this), "BUTTON"); setDialogView(uiList.getLast()); showDialog(SET_ID); reloadUI(); 

SetDialogView просто передает представление в Dialog SET_ID, чтобы я мог вручную назначить ID для представления (для тестирования). ReloadUI () просто находит последнее представление, добавленное к фону LinkedList, и добавляет его в relativeLayout, используя .addView;

Если вам требуется больше кода, пожалуйста, дайте мне знать. Мне не хватает вызова для обновления макетов представления после внесения изменений в дочерние представления relativeLayout? Кажется, что представление становится визуально позиционированным, но фактические LayoutParams не обновляются, поэтому, когда вы устанавливаете Button2 на Button1, он получает старую позицию.

Есть ли способ принудительно установить относительное расположение ремаркетинга?

Я думаю, вы должны попробовать простое решение – замените b.invalidate() на b.requestLayout() . Для получения дополнительной информации проверьте эту ссылку . Я не тестировал его, но надеюсь, что он сработает. Поэтому код должен выглядеть так:

 Buttons b = (Buttons) viewIndex; positioningLayout = new RelativeLayout.LayoutParams(b.getLayoutParams()); positioningLayout.addRule(RelativeLayout.BELOW, viewIdFromList.intValue()); b.setLayoutParams(positioningLayout); b.requestLayout(); 

Или, может быть, вы можете упростить это:

 Buttons b = (Buttons) viewIndex; ((RelativeLayout.LayoutParams) b.getLayoutParams()).addRule(RelativeLayout.BELOW, viewIdFromList.intValue()); b.requestLayout(); 

Кажется, вы на правильном пути, но делаете небольшую ошибку. Без дополнительного кода довольно сложно обеспечить фактическое решение. Но я попытаюсь указать на ошибку.

Смотрите, чтобы относительно позиционировать позиции программно в RelativeLayout, вы должны назначать уникальные идентификаторы для каждого из них.

Подобно,

 Button b = new Button(this); b.setId(1); Button c = new Button(this); c.setId(2); 

Каждый элемент должен иметь уникальные идентификаторы.

Теперь, если вы хотите поместить кнопку b вертикально по центру,

 layout.addRule(RelativeLayout.CENTER_VERTICAL); b.setLayoutParams(layout); 

Теперь, если вы хотите разместить кнопку c ниже,

 layout.addRule(RelativeLayout.BELOW, b.getId()); layout.addRule(RelativeLayout.ALIGN_PARENT_LEFT); b.setLayoutparams(layout); 

Это, безусловно, приведет к кнопке c ниже кнопки b. Как вы сказали, вы можете использовать любую структуру данных по вашему выбору, чтобы отслеживать идентификаторы каждого элемента.

Это только подробный пример того, как вы правильно двигаете кнопку. Итак, сначала создайте уникальный идентификатор для View , т. ids.xml Создайте новый файл ресурсов XML в res/values/ и назовите его ids.xml :

состав

И содержимое ids.xml :

 <?xml version="1.0" encoding="utf-8"?> <resources> <item name="button_1" type="id"/> <item name="button_2" type="id"/> </resources> 

Мы должны установить id для вашего основного макета:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/layout_main"> <!-- the id --> <!-- content of this layout --> </RelativeLayout> 

Затем давайте создадим Button s:

  RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.layout_main); final Button button1 = new Button(this); button1.setId(R.id.button_1); button1.setText("BUTTON 1"); button1.setTextColor(Color.BLACK); final Button button2 = new Button(this); button2.setId(R.id.button_2); button2.setText("BUTTON 2"); button2.setTextColor(Color.BLACK); relativeLayout.addView(button1, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)); relativeLayout.addView(button2, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)); RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams) button1.getLayoutParams(); params1.addRule(RelativeLayout.CENTER_IN_PARENT); // set to the center of screen button1.setLayoutParams(params1); final RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams) button2.getLayoutParams(); params2.addRule(RelativeLayout.ALIGN_PARENT_TOP); params2.addRule(RelativeLayout.ALIGN_PARENT_LEFT); button2.setLayoutParams(params2); button2.setOnClickListener(new View.OnClickListener() { @SuppressLint("NewApi") @Override public void onClick(View v) { /* We need to remove the existing rules and update it! * For API 16 and earlier, set the rule to 0, eg --> layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0); * For API 17 and higher, call layoutParams.removeRule(RelativeLayout.ALIGN_PARENT_LEFT); */ int api = android.os.Build.VERSION.SDK_INT; if (api >= Build.VERSION_CODES.JELLY_BEAN_MR1) { // API level 17 params2.removeRule(RelativeLayout.ALIGN_PARENT_TOP); params2.removeRule(RelativeLayout.ALIGN_PARENT_LEFT); }else if (api < Build.VERSION_CODES.JELLY_BEAN_MR1) { params2.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0); params2.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0); } params2.addRule(RelativeLayout.CENTER_IN_PARENT); params2.addRule(RelativeLayout.BELOW, R.id.button_1); // place below button1 button2.setLayoutParams(params2); } }); 

Поэтому, как только вы нажмете на button2 , он переместится ниже button1 .

Intereting Posts