Страница 1 из 5

Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 22 сен 2011, 03:00
damager82
В этом уроке мы:

- изменяем layout-параметры для уже существующих компонентов экрана

Click here to read this article!

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 11 янв 2012, 12:53
Mikhail_dev
В вашем коде, в метод onStopTrackingTouch добавил код

Код: Выделить всё

	  public void onStopTrackingTouch(SeekBar seekBar) {
		    lParams1.weight = 1;
		    lParams2.weight = 1;
	  }
чтобы после отпускания ползунка, кнопки вновь стали занимать старые положения, с одинаковым весом, но изменения не происходят. Что я делаю не так?

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 11 янв 2012, 14:12
damager82
Добавьте еще строки

Код: Выделить всё

btn1.requestLayout();
btn2.requestLayout();
Он прочтет Layout и перерисует кнопки. Этот метод просто выполняется в settext, поэтому в onProgressChanged его не надо было указывать.

Спасибо за замечание, я пофиксил урок.

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 06 мар 2012, 13:12
Hiktor
Cразу извиняюсь возможно за глупый вопрос , потому как я вообще сел за программирование 3 дня назад :) .
Я вот захотел создать еще 1 сикер бар и 2 кнопки .Как привязать первый ряд кнопок к первому сикер бару , а второй сикербар соответсвенно ко второму ряду кнопок ? А то у меня не получается . При передвижении ползунка на любом сикер баре передвигаются и обе пары кнопок :(
Вот мой код :
package ru.startandroid;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class P018_1_DynamicLayout3Activity extends Activity implements OnSeekBarChangeListener {

SeekBar sbWeight;
SeekBar sb2Weight;
Button btn1;
Button btn2;
Button btn3;
Button btn4;


LinearLayout.LayoutParams lParams1;
LinearLayout.LayoutParams lParams2;
LinearLayout.LayoutParams Params3;
LinearLayout.LayoutParams Params4;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

sbWeight = (SeekBar) findViewById(R.id.sbWeight);
sbWeight.setOnSeekBarChangeListener(this);
sb2Weight = (SeekBar) findViewById(R.id.sb2Weight);
sb2Weight.setOnSeekBarChangeListener(this);

btn1 = (Button) findViewById(R.id.btn1);
btn2 = (Button) findViewById(R.id.btn2);
btn3 = (Button) findViewById(R.id.btn3);
btn4 = (Button) findViewById(R.id.btn4);

lParams1 = (LinearLayout.LayoutParams) btn1.getLayoutParams();
lParams2 = (LinearLayout.LayoutParams) btn2.getLayoutParams();
Params3 = (LinearLayout.LayoutParams) btn3.getLayoutParams();
Params4 = (LinearLayout.LayoutParams) btn4.getLayoutParams();
}


public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
int leftValue = progress;
int rightValue = seekBar.getMax() - progress;
// настраиваем вес
lParams1.weight = leftValue;
lParams2.weight = rightValue;
Params3.weight = leftValue;
Params4.weight = rightValue;
// в текст кнопок пишем значения переменных
btn1.setText(String.valueOf(leftValue));
btn2.setText(String.valueOf(rightValue));
btn3.setText(String.valueOf(leftValue));
btn4.setText(String.valueOf(rightValue));
}

public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}

public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 06 мар 2012, 14:00
KamiSempai
При изменении положения ползунка, отрабатывает один и тот же код.
Вы написали:

Код: Выделить всё

sbWeight.setOnSeekBarChangeListener(this);
sb2Weight.setOnSeekBarChangeListener(this);
Следовательно присвоили одно и то-же событие на перетаскивание ползунка.
Что-бы обработчик события отделял один ползунок от другого, в процедуре onProgressChanged Вам стоит определить какой именно объект вызвал событие, sbWeight или sb2Weight. Ссылка на этот объект сидит в параметре seekBar.

Код: Выделить всё

public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
	int leftValue = progress;
	int rightValue = seekBar.getMax() - progress;
	switch(seekBar) {
		case sbWeight:
			lParams1.weight = leftValue;
			lParams2.weight = rightValue;
			btn1.setText(String.valueOf(leftValue));
			btn2.setText(String.valueOf(rightValue));
			break;
		case sb2Weight:
			Params3.weight = leftValue;
			Params4.weight = rightValue;
			btn3.setText(String.valueOf(leftValue));
			btn4.setText(String.valueOf(rightValue));
			break;
	}
}
PS: На сколько я понял, у Вас совершенно нет опыта объектно ориентированного программирования. Я бы посоветовал Вам, для начала, прочитать хотя-бы одну книгу по Java программированию. Например, "Философия Java" Эккеля- очень хорошая книга.

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 06 мар 2012, 14:01
damager82
В методе onProgressChanged на вход подается seekBar. Вам надо поставить проверку sbWeight это или sbWeight2.
И в зависимости от этого уже кнопки менять.

Вообще, я вам очень рекомендую сначала все-таки java хоть немного посмотреть. Проще будет.
viewtopic.php?f=17&t=147

P.S. Собственно KamiSempai уже все подробно расписал )

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 08 мар 2012, 16:10
Hiktor
Спасибо за ссылки на книжки и за ответы :)

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 04 апр 2012, 20:27
KamiSempai
У меня вопрос по методу requestLayout().
На экране есть кнопка на которую назначено следующее событие:

Код: Выделить всё

private float btnHeigth;
private float btnStep;

public void RunClick(View view) {
	final Button btn = ((Button) view);
	btnHeigth = btn.getMeasuredHeight();
	btnStep = btnHeigth / 10;
	final Timer timer = new Timer();
	TimerTask timerTask = new TimerTask() {
		@Override
		public void run() {
			if(btnHeigth>=0){
				btn.getLayoutParams().height = (int) btnHeigth;
				btn.requestLayout();
				btnHeigth =- btnStep;
			}
			else {timer.cancel();}
		}
	};
	timer.schedule(timerTask, 250, 250);
}
По идее, при нажатии на кнопку, должен запускаться таймер который начинает уменьшать высоту кнопки на заранее определенную величину.
Однако, при вызове метода requestLayout(), в TimerTask, возникает ошибка.

Что то мне подсказывает, что все это из за вызова в потоке :geek:

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 05 апр 2012, 09:58
damager82
KamiSempai писал(а):Что то мне подсказывает, что все это из за вызова в потоке :geek:
Скорее всего. Timer вроде не имеет доступа к UI.
Это через Handler лучше делать.

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 05 апр 2012, 10:59
KamiSempai
Спасибо, попробую через Handler.

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 05 апр 2012, 18:06
KamiSempai
Проверил, работает, причем на много быстрее :)

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 05 май 2012, 10:56
goodroot
А может кто-нибудь подсказать решение такой проблемы?!
У меня есть TableLayout - объявляю я его так

Код: Выделить всё

menu_ataka = (TableLayout)findViewById(R.id.menu_ataka); 
Это layout, который становится VISIBLE при нажатии на определенную кнопку.
Затем, когда мы жмём на кнопку на этом menu_ataka, то его свойства меняются, а именно изменяется его высота.
Изменение его размеров по нажатию я сделал, но как сделать, чтобы эти изменения происходили плавно, т.е. анимированно.
Сейчас это просто

Код: Выделить всё

Menu_height.height = 500;
      menu_ataka.setLayoutParams(Menu_height);
Как всё-таки задать анимацию для имеющегося объекта, когда есть начальное состояние параметра height и конечные???

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 30 май 2012, 20:51
Александр
Так как впервые отписываюсь в комментариях, хочу сначала поблагодарить тебя Дим за сей сайт))) спасибо тебе огромное и дай Бог тебе всего всего и побольше))) а теперь вопрос.....
В методе onStopTrackingTouch
написал вот это: sbWeight.setProgress(50);

т.е. по идеи вес кнопок и показания на них должны остаться такими в какой момент я отпустил бегунок.. и только бегунок должен вернуться на середину, а происходит так что и кнопки становятся равными и надписи на них 50.
пробовал ставить разные цифорки в sbWeight.setProgress(х) складывается такое впечатление, что когда я вызываю sbWeight.setProgress(х) обрабатывается метод onProgressChanged() для значения Х.

Почему так?

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 31 май 2012, 16:36
damager82
Спасибо за отзыв ) Это хорошо, что стараюсь я не зря.
Александр писал(а):В методе onStopTrackingTouch написал вот это: sbWeight.setProgress(50);
складывается такое впечатление, что когда я вызываю sbWeight.setProgress(х) обрабатывается метод onProgressChanged() для значения Х.
Так и есть. Походу ползунку неважно - руками его двигают или программно, в любом случае срабатывает onProgressChanged. Можно какую-нить boolean переменную использовать, чтобы отличать.

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 13 июл 2012, 15:37
Андрей Д
Дмитрий, спасибо за сайт! У Вас явный талант рассказывать понятным и доступным языком о вещах малодоступных и малопонятных. С большим интересом читаю Ваши уроки.

А вопрос у меня теоретический - может кто поможет:
Почему после присвоения
lParams1.weight = leftValue;
нет необходимости вызывать, например
btn1.setLayoutParams(lParams1);
и только потом
btn1.setText(String.valueOf(leftValue))?

Или другими словами - почему после получения lParams1 = (LinearLayout.LayoutParams) btn1.getLayoutParams();
мы, работая с lParams1, непосредственно влияем на btn1?
Связано ли это с тем, что LinearLayout.LayoutParams объявлен как статический класс?

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 13 июл 2012, 16:50
damager82
Андрей Д писал(а):Дмитрий, спасибо за сайт! У Вас явный талант рассказывать понятным и доступным языком о вещах малодоступных и малопонятных. С большим интересом читаю Ваши уроки.

А вопрос у меня теоретический - может кто поможет:
Почему после присвоения
lParams1.weight = leftValue;
нет необходимости вызывать, например
btn1.setLayoutParams(lParams1);
и только потом
btn1.setText(String.valueOf(leftValue))?
Спасибо большое :)


В уроке после последнего скрина есть примечание как раз насчет этого.
Есть небольшой нюанс. Как верно заметили в каментах, если просто написать код lParams1.weight = 1, то компонент не изменится. Необходимо дописать код: btn1.requestLayout(). Тогда кнопка прочтет Layout и перерисуется. Этот метод уже вызывается в setText, поэтому мы его здесь явно не вызываем.
Т.е. lParams1.weight = leftValue; ничего не даст. Надо руками запускать btn1.requestLayout(), если потом не запускаются методы, уже содержащие этот вызов.

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 26 июл 2012, 12:04
mmvds
Такой вопрос, вот мы указываем что обработчик в активити

Код: Выделить всё

public class MainActivity extends Activity implements OnSeekBarChangeListener
а если добавим еще и кнопку и нужно будет отслеживать ее нажатие?
Раньше мы делали обработчик в активити аналогично

Код: Выделить всё

public class MainActivity extends Activity implements OnClickListener
Теперь там уже есть обработчик OnSeekBarChangeListener, код обработки нажатия на кнопку можно впихнуть в него же и сделать дополнительный выбор по id объекта?
Или надо поступать как-то по-другому?

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 26 июл 2012, 12:09
AndreyI
Мы можем реализовывать в классе любое количество интерфейсов (в чем их и прелесть, в отличии от обычного наследования), просто перечислив их через запятую

Код: Выделить всё

public class MainActivity extends Activity implements OnClickListener, OnSeekBarChangeListener

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 26 июл 2012, 12:12
rezak90
один класс может наследовать много интерфейсов (через запятую), а вот наследовать класс - только один.

Re: Урок 18. Меняем layoutParams в рабочем приложении

Добавлено: 26 июл 2012, 14:02
mmvds
AndreyI, rezak90 - спасибо!