TableRow rescales after all elements of row are cl

2019-08-29 09:33发布

问题:

I am creating a Table of buttons, to control a LED Matrix via Bluetooth. I have found on the web Brian's Video Tutorials and followed his Dynamic Buttons and Images video to implement this.

Here is the code:

    public class DrawerMode extends Activity {
    private static final int NUMOFCOL = 15;
    private static final int NUMOFROW = 8;
    Button buttons[][] = new Button[NUMOFROW][NUMOFCOL];

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        //Assign content
        setContentView(R.layout.activity_draw_mod);
        fillTable();



    }

    private void fillTable() {
        TableLayout tableLayout = (TableLayout) findViewById(R.id.drawer_table);
        for( int iter_R = 0; iter_R!= NUMOFROW; iter_R++){
            TableRow tableRow = new TableRow(this);
            tableRow.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT,TableLayout.LayoutParams.WRAP_CONTENT,1.0f));
            tableLayout.addView(tableRow);
            for(int iter_C = 0; iter_C != NUMOFCOL; iter_C++){
                final int FINAL_COL = iter_C;
                final int FINAL_ROW = iter_R;
                Button button = new Button(this);
                button.setLayoutParams(new TableRow.LayoutParams( TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT, 1.0f));
                button.setText("" + iter_C + "," + iter_R);             
                button.setPadding(0, 0, 0, 0);
                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        whenBtnClicked(FINAL_COL, FINAL_ROW);
                    }
                });
                tableRow.addView(button);
                buttons[iter_R][iter_C] = button;
            }
        }
    }

    private void whenBtnClicked(int col, int row) {
        //Toast.makeText(this, "Button clicked: " + FINAL_COL + "," + FINAL_ROW, Toast.LENGTH_SHORT).show();
        Button button = buttons[row][col];
        // Lock Button Sizes:
        lockButtonSizes();
        int newWidth = button.getWidth();
        int newHeight = button.getHeight();
        Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_dark_blue);
        Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalBitmap, newWidth, newHeight, true);
        Resources resource = getResources();
        button.setBackground(new BitmapDrawable(resource, scaledBitmap)); // Change text on button:
        button.setText(" ");
    }

    private void lockButtonSizes(){
        for (int row = 0; row < NUMOFROW; row++){
            for (int col = 0; col < NUMOFCOL; col++){
                Button button = buttons[row][col];
                int width = button.getWidth();
                button.setMinWidth(width);
                button.setMaxWidth(width);
                int height = button.getHeight();
                button.setMinHeight(height);
                button.setMaxHeight(height);
            }
        }
    }
}

It works great, but while testing I have found the following issue.

When I click random buttons it works great:

[img]http://i.imgur.com/OYFJ6zJ.png?1[/img]

But when I complete a row (all elements on row are clicked), and I mean any row it starts to rescale the buttons in the whole table:

[img]http://i.imgur.com/ttAz4U0.png?1[/img]

I was thinking that maybe the LayoutParams of the TableRow should be changed, but not sure about that. What am I missing here?

回答1:

I think you're right about the layout parameters needing to change. This line

tableRow.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT,TableLayout.LayoutParams.WRAP_CONTENT,1.0f));

would cause the row's height to shrink in size if no button had displayed text, which seems to be what's happening. The TableLayout.LayoutParams does support setting fixed width/height, which you could sensibly calculate by first getting the device's screen width/height and dividing accordingly.

Or, if that gets to cumbersome, you could set -- though this may be too much of a hack -- the default text in the TextViews in the "unset" buttons with some transparent text (e.g., "1,1") so that the height is the same as a set button. This SO answer answer shows how to make transparent text.



回答2:

I am certain that this is not a good solution for all cases. But just as I thought, the problem was with

 button.setLayoutParams(new TableRow.LayoutParams( TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT, 1.0f));

If I understand correctly after the entire row was clicked, since the LayoutParams change according to the MATCH_PARENT value, the TableRow rescales the whole row to meet this criteria,since the height of the entire row is the same now. Not sure if it happens exactly this way, but I think this is the case because of my solution.

My work around is to add specific values for the LayoutParams, instead of leaving it the system to figure it out:

button.setLayoutParams(new TableRow.LayoutParams( 75, 50, 1.0f));

I am aware this is not how it should be done. But since I have a deadline to met soon, I can't spend any more time with it. Most likely the correct way to do this is Jason's suggestion to get the screen size and calculate it. You can do this with:

Display display = getWindowManager().getDefaultDisplay(); Point size = new Point();
display.getSize(size); 
int width = size.x; 
int height = size.y;

The problem is to come up with a correct formula to calculate this values you can pass to the LayoutParam. If anyone can figure this out please do post your solution and I will accept that answer. At this point I accept Jason's suggestion.