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.
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;
}
}