首页 > 解决方案 > 无法将 TextView 添加到 LinearLayout

问题描述

我正在为我的 Android 课程做暑期实验室作业。

在 layout_main.xml 我有:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include layout="@layout/main_menu" />

    <fragment
        android:name="tests.tinyplanner.ActivityFragment"
        android:id="@+id/mainActivityFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

在 main_menu.xml 我有:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <tests.tinyplanner.ThemeButton
        android:id="@+id/todoButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/todo_button_title" />

    <tests.tinyplanner.ThemeButton
        android:id="@+id/calendarButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/calendar_button_title" />

    <tests.tinyplanner.ThemeButton
        android:id="@+id/notesButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/notes_button_title" />

</LinearLayout>

对于 layout_main.xml 我有一个类:

package tests.tinyplanner;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;

public class MainLayout extends LinearLayout {
    private View todoButton;
    private View calendarButton;
    private View notesButton;

    private LayoutInflater inflater_;
    private View inflateView_;

    private void doInflate(Context context) {
        this.inflater_ = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.inflateView_ = this.inflater_.inflate(R.layout.layout_main, this);

        this.todoButton = this.inflateView_.findViewById(R.id.todoButton);
        this.calendarButton = this.inflateView_.findViewById(R.id.calendarButton);
        this.notesButton = this.inflateView_.findViewById(R.id.notesButton);

    }

    public MainLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.doInflate(context);
    }

    public MainLayout(Context context) {
        this(context, null);
    }

    public View getTodoButton() {
        return  this.todoButton;
    }

    public View getCaldendarButton() {
        return  this.calendarButton;
    }

    public View getNotesButton() {
        return  this.notesButton;
    }
}

我在 MainActivity 中使用这个布局

this.layout = new MainLayout(this);
TextView logoTextView = (TextView)((LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.logo_layout, null);
((MainLayout) this.layout).addView(logoTextView);
this.setContentView(this.layout);
this.todoButton = ((MainLayout)this.layout).getTodoButton();
this.todoButton.setOnClickListener(this);
this.calendarButton = ((MainLayout)this.layout).getCaldendarButton();
this.calendarButton.setOnClickListener(this);
this.notesButton = ((MainLayout)this.layout).getNotesButton();
this.notesButton.setOnClickListener(this);

所有按钮都正确显示。问题是logoTextView根本不显示。logo_layout是这样的:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:text="@string/logo_title"
    android:id="@+id/logoTextView"
    android:theme="@style/LogoTheme"
        android:layout_height="wrap_content" >

</TextView>

LogoTheme 是这样的:

<style name="LogoTheme">
    <item name="android:textStyle">bold</item>
    <item name="android:textColor">@color/colorFontButtonDefault</item>
    <item name="android:textAllCaps">true</item>
    <item name="android:ems">80</item>
    <item name="android:textSize">18sp</item>
    <item name="android:gravity">center</item>
    <item name="android:textAlignment" tools:targetApi="17">center</item>
</style>

为什么logoTextView不显示?

标签: android

解决方案


您的代码中有几处出错了。在开始之前,让我先澄清一些概念

1) 默认情况下,线性布局的方向为水平。这意味着所有子视图将根据为每个子视图定义的宽度水平堆叠在线性布局内。

  |   ChildA    |   ChildB |  ChildC  |

2)如果任何一个孩子将宽度定义为“MATCH_PARENT”,那么它将不允许在其下方显示其他孩子,如下所示

  | ChildA                             | (Not visible) childB | (Not visible) childC|

基于此信息,让我们尝试了解您的问题

第一件事:在 MainActivity 内部,您尝试创建 MainLayout,您需要为 MainLayout 指定 Orientation

this.layout = new MainLayout(this);
((MainLayout)this.layout).setOrientation(LinearLayout.VERTICAL);

这将允许垂直堆叠所有孩子,以便我们可以看到所有孩子

第二件事:,在layout_main.xml中,请将Linear layout的layout_height定义为“wrap_content”。这将允许您的 logotext 在屏幕上显示

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"    
    android:orientation="vertical">

    <include layout="@layout/main_menu" />

    <fragment
        android:name="tests.tinyplanner.ActivityFragment"
        android:id="@+id/mainActivityFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

编辑:(为什么需要添加方向,即使从 XML 设置它)

让我们检查一下 MainLayout 是如何创建的。首先,我们在 Activity 中创建了 MainLayout 的实例。依次调用主布局内的 doInflatelayout() 。

通过这样做,我们正在做的是,我们创建一个线性布局并在内部膨胀新的线性布局(从 XML 设置方向)

通过查看视图层次结构:

主布局(父)

LinearLayout(在 XML 中带有方向)

线性布局(从 XML 设置 ThemeButton 和方向)

现在你已经为 MainLayout 的第一个孩子设置了方向。但是您没有为 MainLayout 设置方向。

所以我们需要在创建 MainLayout 的时候设置它的 Orientation。

我希望这能帮到您


推荐阅读