TableLayout removeAllViews不删除子项

时间:2014-10-03 18:31:50

标签: java android debugging tablelayout

在我的刷新方法中,我清除了TableRow元素,为新的按钮数组腾出空间,并尝试清除TableLayout,为新近更新的TableRows腾出空间,但我一直收到一条错误,说TableLayout没有被清除。它会出现在table.remveAllViews();没有工作。

MainActivity.java:

package com.example.tilegame;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TableRow.LayoutParams;

public class MainActivity extends ActionBarActivity implements OnClickListener 
{
    TableLayout table;
    Button buttons[];
    int count = 0;
    int btnSize = 0;
    TableRow row;

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

        btnSize = (int)getResources().getDimension(R.dimen.box_size);
        table = (TableLayout)findViewById(R.id.table);      
        buttons = new Button[9];
        row = new TableRow(this);

        for(int x = 0; x < 9; x++)
        {
            if(x < 8)
            {
                Button btn = createButton(btnSize, false, x+1);
                buttons[x] = btn;
            }
            else if(x == 8)
            {
                Button btn = createButton(btnSize, true, x+1);
                buttons[x] = btn;
            }
        }
        randomizeArray(buttons);
        table.removeAllViews();
        for(int x = 0; x < 3; x++)
        {
            TableRow row = new TableRow(this);
            for(int y = 0; y < 3; y++)
            {
                row.addView(buttons[count]);
                count++;
            }
            table.addView(row, x);
        }
    }

    public void onClick(View v)
    {
        switch(v.getId())
        {
            case 0:
                swap(buttons, v.getId());
                refresh();
                break;

            case 1:
                swap(buttons, v.getId());
                refresh();
                break;

            case 2:
                swap(buttons, v.getId());
                refresh();
                break;

            case 3:
                swap(buttons, v.getId());
                refresh();
                break;

            case 4:
                swap(buttons, v.getId());
                refresh();
                break;

            case 5:
                swap(buttons, v.getId());
                refresh();
                break;

            case 6:
                swap(buttons, v.getId());
                refresh();
                break;

            case 7:
                swap(buttons, v.getId());
                refresh();
                break;
        }
    }

    public Button createButton(int size, boolean blank, int id)
    {
        Button btn = new Button(this);

        LayoutParams buttonParams = new LayoutParams(size, size);
        buttonParams.setMargins(5,5,5,5);
        btn.setLayoutParams(buttonParams);
        btn.setId(id);
        btn.setText(""+btn.getId());
        btn.setOnClickListener(this);
        if(blank == false)
        {
            btn.setBackgroundColor(Color.parseColor("#ffffff"));
        }
        else
        {
            btn.setVisibility(View.INVISIBLE);
        }
        return btn;
    }

    public void randomizeArray(Button[] array)
    {
        List<Button> list = new ArrayList<>();
        for(Button i : array)
        {
            list.add(i);
        }
        Collections.shuffle(list);

        for(int x = 0; x < list.size(); x++)
        {
            array[x] = list.get(x);
        }
    }

    public void refresh()
    {
        for(int x = 0; x < 3; x++)
        {
            View child = table.getChildAt(x);
            if(child instanceof TableRow)
            {
                ((ViewGroup) child).removeAllViews();
            }
        }
        table.removeAllViews();
        count = 0;
        for(int x = 0; x < 3; x++)
        {
            for(int y = 0; y < 3; y++)
            {
                row.addView(buttons[count]);
                count++;
            }
            table.addView(row, x);
        }
    }

    public void swap(Button btns[], int id)
    {
        int posClick = 0;
        int posBlank = 0;
        Button temp1 = new Button(this);
        Button temp2 = new Button(this);

        for(int x = 0; x < btns.length; x++)
        {
            if(Integer.parseInt(btns[x].getText().toString()) == id)
            {
                posClick = x;
            }
        }
        for(int x = 0; x < btns.length; x++)
        {
            if(Integer.parseInt(btns[x].getText().toString()) == 9)
            {
                posBlank = x;
            }
        }
        switch(posClick)
        {
            case 0:
                if(posBlank == 1 || posBlank == 3)
                {
                    temp1 = btns[posClick];
                    temp2 = btns[posBlank];
                    btns[posBlank] = temp1;
                    btns[posClick] = temp2;
                }
                break;
            case 1:
                if(posBlank == 0 || posBlank == 2 || posBlank == 4)
                {
                    temp1 = btns[posClick];
                    temp2 = btns[posBlank];
                    btns[posBlank] = temp1;
                    btns[posClick] = temp2;
                }
                break;
            case 2:
                if(posBlank == 1 || posBlank == 5)
                {
                    temp1 = btns[posClick];
                    temp2 = btns[posBlank];
                    btns[posBlank] = temp1;
                    btns[posClick] = temp2;
                }
                break;
            case 3:
                if(posBlank == 0 || posBlank == 4 || posBlank == 6)
                {
                    temp1 = btns[posClick];
                    temp2 = btns[posBlank];
                    btns[posBlank] = temp1;
                    btns[posClick] = temp2;
                }
                break;
            case 4:
                if(posBlank == 1 || posBlank == 3 || posBlank == 5 || posBlank == 7)
                {
                    temp1 = btns[posClick];
                    temp2 = btns[posBlank];
                    btns[posBlank] = temp1;
                    btns[posClick] = temp2;
                }
                break;
            case 5:
                if(posBlank == 2 || posBlank == 4 || posBlank == 8)
                {
                    temp1 = btns[posClick];
                    temp2 = btns[posBlank];
                    btns[posBlank] = temp1;
                    btns[posClick] = temp2;
                }
                break;
            case 6:
                if(posBlank == 3 || posBlank == 7)
                {
                    temp1 = btns[posClick];
                    temp2 = btns[posBlank];
                    btns[posBlank] = temp1;
                    btns[posClick] = temp2;
                }
                break;
            case 7:
                if(posBlank == 4 || posBlank == 6 || posBlank == 8)
                {
                    temp1 = btns[posClick];
                    temp2 = btns[posBlank];
                    btns[posBlank] = temp1;
                    btns[posClick] = temp2;
                }
                break;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
    {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) 
        {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

activity_main.xml中:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/outside"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.tilegame.MainActivity" >

    <TableLayout
        android:id="@+id/table"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#38c0f4"
        android:layout_gravity="center|top" >

        <TableRow
            android:id="@+id/row1">

            <Button
                android:id="@+id/num_1"
                android:layout_width="@dimen/box_size"
                android:layout_height="@dimen/box_size"
                android:background="#FFFFFF"
                android:layout_weight="1"
                android:layout_margin="5dip"
                android:text="@string/num_1">
            </Button>

            <Button
                android:id="@+id/num_2"
                android:layout_width="@dimen/box_size"
                android:layout_height="@dimen/box_size"
                android:background="#FFFFFF"
                android:layout_weight="1"
                android:layout_margin="5dip"
                android:text="@string/num_2">
            </Button>

            <Button
                android:id="@+id/num_3"
                android:layout_width="@dimen/box_size"
                android:layout_height="@dimen/box_size"
                android:background="#FFFFFF"
                android:layout_weight="1"
                android:layout_margin="5dip"
                android:text="@string/num_3">
            </Button>
        </TableRow>

        <TableRow
            android:id="@+id/row2">

            <Button
                android:id="@+id/num_4"
                android:layout_width="@dimen/box_size"
                android:layout_height="@dimen/box_size"
                android:layout_margin="5dip"
                android:layout_weight="1"
                android:background="#FFFFFF"
                android:text="@string/num_4" />

            <Button
                android:id="@+id/num_5"
                android:layout_width="@dimen/box_size"
                android:layout_height="@dimen/box_size"
                android:layout_margin="5dip"
                android:layout_weight="1"
                android:background="#FFFFFF"
                android:text="@string/num_5" />

            <Button
                android:id="@+id/num_6"
                android:layout_width="@dimen/box_size"
                android:layout_height="@dimen/box_size"
                android:layout_margin="5dip"
                android:layout_weight="1"
                android:background="#FFFFFF"
                android:text="@string/num_6" />
        </TableRow>

        <TableRow
            android:id="@+id/row3">

            <Button
                android:id="@+id/num_7"
                android:layout_width="@dimen/box_size"
                android:layout_height="@dimen/box_size"
                android:background="#FFFFFF"
                android:layout_weight="1"
                android:layout_margin="5dip"
                android:text="@string/num_7">
            </Button>

            <Button
                android:id="@+id/num_8"
                android:layout_width="@dimen/box_size"
                android:layout_height="@dimen/box_size"
                android:background="#FFFFFF"
                android:layout_weight="1"
                android:layout_margin="5dip"
                android:text="@string/num_8">
            </Button>

            <Button
                android:id="@+id/blank"
                android:layout_width="@dimen/box_size"
                android:layout_height="@dimen/box_size"
                android:visibility="invisible"
                android:layout_weight="1"
                android:layout_margin="5dip">
            </Button>
        </TableRow>
    </TableLayout>

</LinearLayout>

Log Cat(喵):

10-04 03:07:10.187: E/AndroidRuntime(11284): FATAL EXCEPTION: main
10-04 03:07:10.187: E/AndroidRuntime(11284): Process: com.example.tilegame, PID: 11284
10-04 03:07:10.187: E/AndroidRuntime(11284): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
10-04 03:07:10.187: E/AndroidRuntime(11284):    at android.view.ViewGroup.addViewInner(ViewGroup.java:3771)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at android.view.ViewGroup.addView(ViewGroup.java:3624)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at android.widget.TableLayout.addView(TableLayout.java:429)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at android.view.ViewGroup.addView(ViewGroup.java:3569)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at android.widget.TableLayout.addView(TableLayout.java:411)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at com.example.tilegame.MainActivity.refresh(MainActivity.java:167)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at com.example.tilegame.MainActivity.onClick(MainActivity.java:107)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at android.view.View.performClick(View.java:4640)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at android.view.View$PerformClick.run(View.java:19421)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at android.os.Handler.handleCallback(Handler.java:733)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at android.os.Handler.dispatchMessage(Handler.java:95)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at android.os.Looper.loop(Looper.java:136)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at android.app.ActivityThread.main(ActivityThread.java:5476)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at java.lang.reflect.Method.invokeNative(Native Method)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at java.lang.reflect.Method.invoke(Method.java:515)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
10-04 03:07:10.187: E/AndroidRuntime(11284):    at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:0)

在你的oncreate中你正在做

    for(int x = 0; x < 3; x++)
    {
        TableRow row = new TableRow(this);
        for(int y = 0; y < 3; y++)
        {
            row.addView(buttons[count]);
            count++;
        }
        table.addView(row, x);
    }

但您的刷新代码包含:

    for(int x = 0; x < 3; x++)
    {
        for(int y = 0; y < 3; y++)
        {
            row.addView(buttons[count]);
            count++;
        }
        table.addView(row, x);
    }

由于在这种情况下您没有创建本地行对象,因此您尝试将类行变量多次添加到刷新表中。最好删除TableRow行;来自您的类,因为您对方法变量使用相同的命名约定,并且没有在我可以看到的任何地方使用类作用域row