Trevin Avery
Trevin Avery

Reputation: 2919

View not showing all content after scaling down

After using the View.setScaleX() and View.setScaleY() methods to make my view smaller, the result only shows the content that was already displayed, leaving out the rest that didn't fit on the screen when it was zoomed in. How can I force it to show the rest of the content?

XML: activity_main.xml

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/table"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

JAVA: MainActivity.java

package com.example.zoom;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class MainActivity extends Activity {

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

        TableLayout table = (TableLayout) findViewById(R.id.table);

        int textViewSize = 100;
        int tableColCount = 15;
        int tableRowCount = 15;

        for (int row = 0; row < tableRowCount; row++) {
            TableRow tr = new TableRow(this);
            for (int col = 0; col < tableColCount; col++) {
                TextView textView = new TextView(this);
                textView.setText("" + row + "." + col);
                textView.setTextSize(20.0f);
                tr.addView(textView, textViewSize, textViewSize);
            } // for
            table.addView(tr);
        } // for
    }

    @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) {

        LinearLayout table = (LinearLayout) findViewById(R.id.table);

        switch (item.getItemId()) {

            case R.id.action_zoom_in:
                table.setScaleX(1.0f);
                table.setScaleY(1.0f);
                break;
            case R.id.action_zoom_out:
                table.setScaleX(0.25f);
                table.setScaleY(0.25f);
                break;
        } // switch
        return true;
    }
}

SCREEN SHOTS: Zoomed In | Zoomed Out

I noticed this question was very much the same as mine, but there was no code nor answer.

Upvotes: 0

Views: 2009

Answers (1)

Trevin Avery
Trevin Avery

Reputation: 2919

As it turns out setting the size of the view manually (instead of using wrap_content) did the trick. This is all it really took:

FrameLayout.LayoutParams tableLP = new FrameLayout.LayoutParams(
    textViewSize * tableColCount, textViewSize * tableRowCount);
table.setLayoutParams(tableLP);

I also set the pivot point to 0 to keep the view in the top left corner.

table.setPivotX(0);
table.setPivotY(0);

In regards to pskink (who commented on my original question) I looked into animations and discovered that using a ViewPropertyAnimator did a pretty nice job as well. To use this class you just call View.animate().

After setting the size of the view that will be scaled, and the pivot point of that view, you can either use the basic scaling method with no animation,

// zoom in by 50%
float scale = 0.5f;
view.setScaleX(table.getScaleX() + scale);
view.setScaleY(table.getScaleY() + scale);

or the scaling method with animation.

// zoom in by 50%
float scale = 0.5f;
table.animate().scaleXBy(scale).scaleYBy(scale).setDuration(0).start();

Here is a full example of the program in the original question:

package com.example.zoom;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.FrameLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class MainActivity extends Activity {

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

        TableLayout table = (TableLayout) findViewById(R.id.table);

        int textViewSize = 100;
        int tableColCount = 15;
        int tableRowCount = 15;

        for (int row = 0; row < tableRowCount; row++) {
            TableRow tr = new TableRow(this);
            for (int col = 0; col < tableColCount; col++) {
                TextView textView = new TextView(this);
                textView.setText(row + "." + col);
                textView.setTextSize(20.0f);
                tr.addView(textView, textViewSize, textViewSize);
            } // for
            table.addView(tr);
        } // for

        // manually set the size to make sure the entire view is drawn and will be seen when scaled down
        FrameLayout.LayoutParams tableLP = new FrameLayout.LayoutParams(textViewSize * tableColCount, textViewSize * tableRowCount);
        table.setLayoutParams(tableLP);
    }

    @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) {

        TableLayout table = (TableLayout) findViewById(R.id.table);
        // set default scale to 0 in case no scale occurs
        float scale = 0.0f;

        switch (item.getItemId()) {

            case R.id.action_zoom_in:
                scale = 0.5f;
                break;
            case R.id.action_zoom_out:
                // use negative to decrease the scale
                scale = -0.5f;
                break;
        } // switch

        // set pivot to 0 to keep view in the top left corner
        table.setPivotX(0);
        table.setPivotY(0);
        // add new scale with current scale to get View.scaleBy() equivalent
        table.setScaleX(table.getScaleX() + scale);
        table.setScaleY(table.getScaleY() + scale);
//      could use an animation instead
//      table.animate().scaleXBy(scale).scaleYBy(scale).setDuration(0).start();
        return true;
    }
}

Upvotes: 1

Related Questions