Как использовать параметр xml в представлении действия?

#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 , и иметь main FrameLayout с идентификатором, установленным с помощью setContentView() , чтобы вы могли использовать его с помощью findViewById() и могли добавлять / удалять представления более гибким способом.

3. @bigstones Я вас не совсем понимаю: что вы имеете в виду под основным описанием фрейма? (Вы имеете в виду MapView в моем случае и два других xml-файла?) Должен ли я в любом случае добавлять представления с FrameLayout.LayoutParams или есть способ перенять XML-макет?

4. @bigstones это работает! Спасибо! И извините за мой ужасный английский

5. @AnWi: добро пожаловать, помните, что вы можете принимать ответы, чтобы поблагодарить людей 😉 (нажмите зеленую галочку рядом с вопросом под голосованием)