片段未显示在框架布局中

fragments not displaying in framelayout

简介:

具体来说,我正在尝试使用片段来创建数独游戏。

数独板由 9 个子网格组成,每个子网格包含 9 个单元格,因此一个网格中有 9 个单元格,其中 9 个网格组成数独板,以 3x3 的方式排列。


方法:

主屏幕包含一些信息,其中 GridLayout 包含 9 Framelayouts,其中每个数独碎片将被放入

9 个数独碎片将组成数独棋盘。

sudoku_cellonClickListener 扩展了 LinearLayout,因为扩展了 TextView,所以我无法膨胀 sudoku_cell 布局(是吗可以这样做吗?)

在我的主要 activity 中,我有一个包含 9 个 FrameLayout 的 GridLayout。这些布局将列和行位置设置为形成一个 3x3 矩阵,这是每个片段将添加到的位置。

这些框架布局以基于 0 的索引命名:frame00frame01frame02frame10


文档说:

developer.android.com 中所述,我需要:


问题:

TL;DR:简单地说,我的片段没有显示。

调用 commit() 后,我希望看到一个 3x3 的 sudoku_grid 片段板,每个包含 9 sudoku_cells。但是,这不会显示

我搜索了 SO,重新阅读了文档,并进行了更多搜索,但不明白为什么它没有显示。


我试过了:

在填充我的片段时,我填充了一个 sudoku_cell 布局,这实际上显示了一个 9 单元网格。

但是每个单元格应该是一个包含 9 个单元格的网格,这让我相信 Sudoku_Grid - Sudoku_Cell 方面可能存在问题,可能是 sudoku_cell 布局未正确充气或未正确扎根。

通常会传递 LayoutInflatorViewGroup 以允许对布局进行扩充,但在 sudoku_cell 的情况下,我找不到这样的方法 override,是这个原因吗?


代码:

sudoku_cell.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <TextView
            android:id="@+id/cellText"
            android:layout_width="35dp"
            android:layout_margin="1px"
            android:textSize="18dp"
            android:layout_height="35dp"
            android:textAlignment="center"
            android:textColor="@color/clBlack">
    </TextView>
</LinearLayout>

SudokuCell.java

public class SudokuCell extends LinearLayout{

    private LinearLayout layout;
    private TextView textView;
    private Context mContext;
    private Point location;
    private int index;

    public SudokuCell(Context context) {
        super(context);
    }

    public SudokuCell(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;

        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        layout = (LinearLayout) inflater.inflate(R.layout.sudoku_cell, this, true);

        textView = layout.findViewById(R.id.cellText);
        setText("");
    }

    public void setStaticText(String s){
        if (textView != null) {
            textView.setText(s);
            textView.setTypeface(textView.getTypeface(), Typeface.BOLD);
        }
    }

    public void setText(String s){
        if (textView != null)
            textView.setText(s);
    }

    public Point getLocation() {
        return location;
    }

    public void setLocation(Point location) {
        this.location = location;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }
}

9 个 sudoku_cell 被添加到 sudoku_grid 中,如下面的 onCreateView()populateGrid() 方法所示:

sudoku_grid.xml

<?xml version="1.0" encoding="utf-8"?>
<GridLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="2px"
        android:id="@+id/grid_layout"
        android:columnCount="3"
        android:rowCount="3">

</GridLayout>

SudokuGrid.java

public class SudokuGrid extends Fragment{

    private GridLayout gridLayout;
    private List<GridFragmentListener> listeners = new ArrayList<>();
    private Context mActitityContext;
    private boolean FRAGMENT_LOCATION_CENTRE;
    private float SCREEN_DP;
    private int GRID_MARGINS_DP = 1;
    private int colorOdd, colorEven;
    private List<Integer> presetGrid;
    private View previousView;
    private Drawable previousViewDrawable;

    public void addGridListener(GridFragmentListener gridFragmentListener) {
        listeners.add(gridFragmentListener);
    }

    public void removeGridListener(GridFragmentListener gridFragmentListener) {
        listeners.remove(gridFragmentListener);
    }

    protected void notifyValueChanged(View value) {
        for (GridFragmentListener listener : listeners) listener.onValueChange(value);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mActitityContext = getActivity();
        View v = inflater.inflate(R.layout.sudoku_grid, container, false);

        //set grid view
        gridLayout = v.findViewById(R.id.grid_layout);

        populateGrid();
        return v;
    }

    private void populateGrid() {

        for (int i = 0; i < 9; i++) {
            SudokuCell sudokuCell = new SudokuCell(mActitityContext);
            sudokuCell.setBackgroundColor(((i % 2) == 0) ? R.color.clOdd : R.color.clEven);
            System.out.printf("Sudoku Cell ID [ index = " + String.valueOf(i) + " ] - getId() = " + sudokuCell.getId());
            sudokuCell.setLocation(getPoint(i));
            sudokuCell.setIndex(i);
            sudokuCell.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    notifyValueChanged(view);
                }
            });
            sudokuCell.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View view, boolean b) {
                    SudokuCell cell = (SudokuCell) view;
                    if (b)
                        view.setBackgroundColor(ContextCompat.getColor(mActitityContext, R.color.clSelected));
                    else
                    view.setBackgroundColor(ContextCompat.getColor(mActitityContext, (cell.getIndex() % 2 == 0) ? R.color.clOdd : R.color.clEven));
                }
            });
            sudokuCell.setStaticText(String.valueOf(i));
            gridLayout.addView(sudokuCell, i);
        }
    }

    private Point getPoint(int i) {
        int y = 0;
        while (i > 2){
            y++;
            i -= 3;
        }
        return new Point(i, y);
    }

    @Override
    public void onStart() {
        super.onStart();
        try {
            addGridListener((GridFragmentListener) getActivity());
        } catch (ClassCastException e) {
            throw new ClassCastException(
                    getActivity().getClass().toString()
                            + " does not implement the DetailsFragment.DetailsFragmentListener interface.");
        }

    }

    @Override
    public void onStop() {
        super.onStop();
        removeGridListener((GridFragmentListener) getActivity());
    }
}

在我的主要 activity 中,我处理了 9 个 sudoku_grid 片段的创建,这些片段被放置到每个 FrameLayout 中,以形成 Sudoku_Grid 的 3x3 矩阵, 这将构成数独板

activity_main_sudoku.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="wrap302.nmu.task1.MainActivitySudoku"
        android:background="@color/clDarkGrey">

    <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" android:id="@+id/linearLayout2">
        <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/textView"
                android:text="@string/app_title"
                android:layout_marginTop="5dp"
                android:layout_marginBottom="5dp"
                android:textColor="@color/clWhite"
                android:textAppearance="@style/TextAppearance.AppCompat.Display1"
                android:textAlignment="center"
                android:textStyle="bold"
                android:fontFamily="sans-serif"/>
        <TextView
                android:text="@string/lblScore"
                android:textColor="@color/clWhite"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" android:id="@+id/lblScore"
                android:textAppearance="@style/TextAppearance.AppCompat.Button" android:textAlignment="center"
                android:layout_marginBottom="5dp"/>
    </LinearLayout>

    <GridLayout
            android:layout_gravity="center"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:columnCount="3"
            android:rowCount="3"
            android:id="@+id/main_sudokugrid_container">
        <FrameLayout
                android:layout_column="0"
                android:layout_row="0"
                android:layout_width="wrap_content"
                android:background="@color/clWhite"
                android:layout_height="wrap_content" android:id="@+id/frame00"/>
        <FrameLayout
                android:layout_column="1"
                android:layout_row="0"
                android:layout_width="wrap_content"
                android:background="@color/clWhite"
                android:layout_height="wrap_content" android:id="@+id/frame01"/>
        <FrameLayout
                android:layout_column="2"
                android:layout_row="0"
                android:layout_width="wrap_content"
                android:background="@color/clWhite"
                android:layout_height="wrap_content" android:id="@+id/frame02"/>
        <FrameLayout
                android:layout_column="0"
                android:layout_row="1"
                android:layout_width="wrap_content"
                android:background="@color/clWhite"
                android:layout_height="wrap_content" android:id="@+id/frame10"/>
        <FrameLayout
                android:layout_column="1"
                android:layout_row="1"
                android:layout_width="wrap_content"
                android:background="@color/clWhite"
                android:layout_height="wrap_content" android:id="@+id/frame11"/>
        <FrameLayout
                android:layout_column="2"
                android:layout_row="1"
                android:layout_width="wrap_content"
                android:background="@color/clWhite"
                android:layout_height="wrap_content" android:id="@+id/frame12"/>
        <FrameLayout
                android:layout_column="0"
                android:layout_row="2"
                android:layout_width="wrap_content"
                android:background="@color/clWhite"
                android:layout_height="wrap_content" android:id="@+id/frame20"/>
        <FrameLayout
                android:layout_column="1"
                android:layout_row="2"
                android:layout_width="wrap_content"
                android:background="@color/clWhite"
                android:layout_height="wrap_content" android:id="@+id/frame21"/>
        <FrameLayout
                android:layout_column="2"
                android:layout_row="2"
                android:layout_width="wrap_content"
                android:background="@color/clWhite"
                android:layout_height="wrap_content" android:id="@+id/frame22"/>
    </GridLayout>

    <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:gravity="center" android:id="@+id/linearLayout">
        <GridLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:paddingTop="0dp">
            <Button
                    android:layout_row="0"
                    android:layout_column="0"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/btn1"
                    android:text="1"/>
            <Button
                    android:layout_row="0"
                    android:layout_column="1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/btn2"
                    android:text="2"/>
            <Button
                    android:layout_row="0"
                    android:layout_column="2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/btn3"
                    android:text="3"/>
            <Button
                    android:layout_row="1"
                    android:layout_column="0"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/btn4"
                    android:text="4"/>
            <Button
                    android:layout_row="1"
                    android:layout_column="1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/btn5"
                    android:text="5"/>
            <Button
                    android:layout_row="1"
                    android:layout_column="2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/btn6"
                    android:text="6"/>
            <Button
                    android:layout_row="2"
                    android:layout_column="0"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/btn7"
                    android:text="7"/>
            <Button
                    android:layout_row="2"
                    android:layout_column="1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/btn8"
                    android:text="8"/>
            <Button
                    android:layout_row="2"
                    android:layout_column="2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/btn9"
                    android:text="9"/>
            <Button
                    android:layout_row="0"
                    android:layout_column="3"
                    android:layout_rowSpan="3"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="fill_vertical"
                    android:id="@+id/btnClear"
                    android:text="Clear"/>
        </GridLayout>
    </LinearLayout>
</RelativeLayout>

MainActivitySudoku.java

public class MainActivitySudoku extends AppCompatActivity implements GridFragmentListener {

    private FragmentManager fragmentManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_sudoku);
        createSudokuGrid();
    }

    private void createSudokuGrid() {
        fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransactionManager = fragmentManager.beginTransaction();

        fragmentTransactionManager.add(R.id.frame00, new SudokuGrid());
        fragmentTransactionManager.add(R.id.frame01, new SudokuGrid());
        fragmentTransactionManager.add(R.id.frame02, new SudokuGrid());
        fragmentTransactionManager.add(R.id.frame10, new SudokuGrid());
        fragmentTransactionManager.add(R.id.frame11, new SudokuGrid());
        fragmentTransactionManager.add(R.id.frame12, new SudokuGrid());
        fragmentTransactionManager.add(R.id.frame20, new SudokuGrid());
        fragmentTransactionManager.add(R.id.frame21, new SudokuGrid());
        fragmentTransactionManager.add(R.id.frame22, new SudokuGrid());

        fragmentTransactionManager.commit();

    }

    @Override
    protected void onStart() {
        super.onStart();
        Toast.makeText(this, "Activity Started & Viewable", Toast.LENGTH_SHORT).show();
    }

    // GridFragmentListener
    @Override
    public void onValueChange(View view) {
        //todo something here with received view
    }
}

好吧,事实证明解决方案比预期的要简单。

简而言之,解决方案是将 SudokuCell 构造函数代码从

SudokuCell(Context context, AttributeSet attrs)

SudokuCell(Context context)

因为那是我调用的构造函数。

可以做一些其他的改进来改进,这解决了片段不显示的问题。

很简单的错误

好的 - 我已经为您提供了如何添加片段以便它们显示的示例。如果您完成此过程并模拟该过程,这将对您有所帮助。我在布局中使用了基本示例,因此我们可以在 类.

中使用 id

您还需要管理应用程序生命周期和后退按钮,了解您希望如何使用片段管理堆栈和维护任何数据。

Activity

public class MyActivity extends Activity {

    Fragment fragment;
    FrameLayout frameLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_myactivity);
        View view = this.findViewById(android.R.id.content);
        frameLayout = (FrameLayout) findViewById(R.id.frag);

        fragment = new MyFragment();
        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.frag, fragment);
        fragmentTransaction.commit();
    }
}

Activity

的布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                .../...>
    .../...

    <FrameLayout
        android:id="@+id/frag"
        // sort out your layout here with the frameLayouts
        android:layout_below="@+id/your_id"
    />
    .../...

</RelativeLayout>

片段

public class MyFragmentextends Fragment {

    FragmentManager fragmentManager;
    Fragment fragment;


    public static MyFragmentnewInstance(String item {
        fragment =
                new MyFragment();
        // pass data from activity
        Bundle args = new Bundle();
        args.putString(ITEM, item);
        fragment.setArguments(args);
        return fragment;
    }

    public DeliveryDisplayFromDispenserFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            item = getArguments().getString(ITEM);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view =
                inflater.inflate(R.layout.myfragment, container, false);
    }
}

片段布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        .../...>

    // fragment layout
</RelativeLayout>