#android #view
#Android #Вид
Вопрос:
Я хочу показать два представления в одном действии. Если я нажал на кнопку в первом представлении, я хочу увидеть второе и наоборот. Представления не должны иметь того же размера, что и экран, поэтому я хочу, например, расположить его по центру, как вы видите в first.xml.
Но если я добавлю представления с
addContentView(mFirstView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
представления не центрированы. Они показаны в левом верхнем углу.
Как я могу использовать настройки xml, например, для центрирования?
first.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:background="@drawable/background"
android:layout_gravity="center"
android:minWidth="100dp"
android:minHeight="100dp"
android:paddingBottom="5dp"
>
<LinearLayout android:id="@ id/head"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton android:id="@ id/first_button"
android:src="@drawable/show_second"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null" />
</LinearLayout>
second.xml то же, что first.xml но с
<ImageButton android:id="@ id/second_button"
android:src="@drawable/show_first"
... />
ShowMe.java
public class ShowMe extends Activity {
View mFirstView = null;
View mSecondView = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initFirstLayout();
initSecondLayout();
showFirst();
}
private void initFirstLayout() {
LayoutInflater inflater = getLayoutInflater();
mFirstView = inflater.inflate(R.layout.first, null);
getWindow().addContentView(mFirstView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
ImageButton firstButton = (ImageButton)mMaxiView.findViewById(R.id.first_button);
firstButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ShowMe.this.showSecond();
}
});
}
private void initSecondLayout() {
// like initMaxiLayout()
}
private void showFirst() {
mSecondView.setVisibility(View.INVISIBLE);
mFirstView.setVisibility(View.VISIBLE);
}
private void showSecond() {
mFirstView.setVisibility(View.INVISIBLE);
mSecondView.setVisibility(View.VISIBLE);
}}
Надеюсь, кто-нибудь сможет помочь.
Спасибо
Ответ №1:
Почему вы не используете setContentView(R.layout.yourlayout)
? Я полагаю, что новые, которые LayoutParams
вы передаете addContentView()
, переопределяют те, которые вы определили в xml.
Кроме того, ViewGroup.LayoutParams
отсутствует параметр layout gravity, поэтому вам придется использовать правильный для макета, в который вы собираетесь добавить представление (я подозреваю, что это FrameLayout
, вы можете проверить с помощью Hierarchy Viewer). Это также общее правило, которому следует следовать. При использовании методов, которые принимают ресурсы макета в качестве аргументов, это происходит автоматически (они могут запросить предполагаемого родителя).
Учитывая это соображение, вы могли бы задать параметры макета с помощью:
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(/* wrap wrap */);
lp.setGravity(Gravity.CENTER);
addContentView(mYourView, lp);
Но я бы рекомендовал setContentView()
, если у вас нет особых потребностей.
Редактировать
Я имею в виду, что вы создаете макет, подобный:
~~~ /res/layout/main.xml
~~~
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="....."
android:id="@ id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
затем в вашем onCreate()
или init...Layout()
:
setContentView(R.layout.main);
FrameLayout mainLayout = (FrameLayout)findViewById(R.id.mainLayout);
// this version of inflate() will automatically attach the view to the
// specified viewgroup.
mFirstView = inflater.inflate(R.layout.first, mainLayout, true);
это сохранит параметры макета из xml, потому что он знает, какой тип ему нужен. Смотрите ссылку.
Комментарии:
1. Если я использую setContentView(), могу ли я получить это представление, чтобы сохранить его в mFirstView / mSecondView? В противном случае я должен инициализировать (в моем реальном коде это больше похоже на кнопку в нем) два представления после каждого вызова setContentView, или? В другом случае я использую setContentView() с помощью (Google) MapView и хочу добавить эти два представления, которые не полностью перекрывают mapview. Я думаю, что в этом случае я не могу использовать setContentView(), или? Если я не использую setContentView(), нет ли способа использовать макет, который уже определен в xml? Чтобы мне не приходилось устанавливать ее снова в коде типа «lp.setGravity(Гравитация. В ЦЕНТРЕ)»?
2. @AnWi: хм, похоже, у вас действительно есть особые потребности. С
setContentView()
вам пришлось бы инициализировать представления, потому что это раздувает их непосредственно из xml. Я предлагаю раздуть их с помощьюLayoutInflater
в вашmFirstView
/mSecondView
, и иметь mainFrameLayout
с идентификатором, установленным с помощьюsetContentView()
, чтобы вы могли использовать его с помощьюfindViewById()
и могли добавлять / удалять представления более гибким способом.3. @bigstones Я вас не совсем понимаю: что вы имеете в виду под основным описанием фрейма? (Вы имеете в виду MapView в моем случае и два других xml-файла?) Должен ли я в любом случае добавлять представления с
FrameLayout.LayoutParams
или есть способ перенять XML-макет?4. @bigstones это работает! Спасибо! И извините за мой ужасный английский
5. @AnWi: добро пожаловать, помните, что вы можете принимать ответы, чтобы поблагодарить людей 😉 (нажмите зеленую галочку рядом с вопросом под голосованием)