Масштабирование ImageView до ширины устройства
В моем приложении для Android у меня есть активность, которая показывает изображения, имеющие следующий размер 244 x 330
.
Я хочу показать эти изображения в полной ширине устройства.
Мой файл макета выглядит следующим образом:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ImageView android:id="@+id/news_image"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_marginLeft="18dip"
android:layout_marginRight="18dip"
android:background="#aaaaaa" />
</LinearLayout>
</ScrollView>
Я попытался установить ScaleType для ImageView, но нет ScalingType, который масштабирует ImageView пропорционально.
Как я могу масштабировать изображение пропорционально для всего экрана в альбомном режиме и в портретном режиме?
В принципе, я хочу что-то вроде ScaleType.CENTER_CORP, но также устанавливает пропорциональную высоту для изображения, чтобы я мог видеть все это, а не только часть изображения.
Измените причину, я знаю, что я запутываю вас своими "странными" квестами.
Я хочу показать это вам с изображением.
Это то, что я получаю в данный момент с моей компоновкой. Я хочу заполнить всю серовую область, масштабируя изображение настолько, насколько это необходимо. Как я могу это сделать?
![5vhMM.png]()
Когда я устанавливаю ScaleType
в CENTER_CROP
, я получаю этот
![jMS4f.png]()
но это не то, что я хочу, потому что вы не видите изображение целиком только из центра.
И вот что я хочу:
![52Mt1.png]()
Надеюсь, это поможет вам понять, чего я пытаюсь достичь.
Кто-нибудь знает, как это сделать?
Изменить 2:
Может показаться странным и немного запутанным, что я пытаюсь отобразить изображение, которое больше по высоте, чем размер экрана, но так как я использую ScrollView
в моем макете примера, это должно быть хорошо, а пользователь может прокручиваться, если он хочет видеть не отображаемую область.
Надеюсь, это поможет понять, что я пытаюсь сделать.
Ответы
Ответ 1
Я пробовал каждый ScaleType
в моем ImageView
с fill_parent
и wrap_content
, но никто из них не работал. Я также пробовал все, что я нашел в Google, но ничто не работало для меня, так что я придумал что-то само по себе.
Было ясно, что ImageView не масштабирует мое изображение, как будто я хотел масштабироваться, поэтому мне пришлось масштабировать его самостоятельно. После масштабирования растрового изображения я установил новый Bitmap в качестве источника изображения в ImageView. Это работает очень хорошо и выглядит очень хорошо на G1 и на Motorola Milestone 2.
И вот все части моего кода
Разметка:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/news_wrapper">
<ImageView android:id="@+id/news_image"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_marginLeft="18dip"
android:layout_marginRight="18dip"
android:background="#aaaaaa" />
</LinearLayout>
</ScrollView>
Деятельность
public class ScalingImages extends Activity {
private ImageView imageView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_margin);
this.imageView = (ImageView)findViewById(R.id.news_image);
// The image is coming from resource folder but it could also
// load from the internet or whatever
Drawable drawable = getResources().getDrawable(R.drawable.img);
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
// Get scaling factor to fit the max possible width of the ImageView
float scalingFactor = this.getBitmapScalingFactor(bitmap);
// Create a new bitmap with the scaling factor
Bitmap newBitmap = Util.ScaleBitmap(bitmap, scalingFactor);
// Set the bitmap as the ImageView source
this.imageView.setImageBitmap(newBitmap);
}
private float getBitmapScalingFactor(Bitmap bm) {
// Get display width from device
int displayWidth = getWindowManager().getDefaultDisplay().getWidth();
// Get margin to use it for calculating to max width of the ImageView
LinearLayout.LayoutParams layoutParams =
(LinearLayout.LayoutParams)this.imageView.getLayoutParams();
int leftMargin = layoutParams.leftMargin;
int rightMargin = layoutParams.rightMargin;
// Calculate the max width of the imageView
int imageViewWidth = displayWidth - (leftMargin + rightMargin);
// Calculate scaling factor and return it
return ( (float) imageViewWidth / (float) bm.getWidth() );
}
}
Класс Util
public class Util {
public static Bitmap ScaleBitmap(Bitmap bm, float scalingFactor) {
int scaleHeight = (int) (bm.getHeight() * scalingFactor);
int scaleWidth = (int) (bm.getWidth() * scalingFactor);
return Bitmap.createScaledBitmap(bm, scaleWidth, scaleHeight, true);
}
}
Если есть лучший или более точный способ сделать то же масштабирование , пожалуйста, дайте мне знать, потому что я не могу поверить, что такая тривиальная вещь так трудно выполнить.
Я действительно надеюсь увидеть лучший способ сделать это.
Спасибо, что прочитали.
Ответ 2
Самый простой способ - добавить android: adjustViewBounds = "true" в ImageView и установить тип шкалы в "fitCenter"
Ответ 3
Немного смущен тем, что вы ищете, точно. Если вы масштабируетесь, чтобы соответствовать экрану, у вас есть три варианта, два из которых жизнеспособны, если вы сохраняете пропорции. Вы можете использовать ScaleType fitCenter, который сделает изображение подходящим в пределах пропорционально, или вы можете использовать centerCrop (который, как вы сказали, вы пытались), который растянет кратчайшую сторону изображения, чтобы соответствовать контейнеру (что означает, что некоторые из них будут обрезаны на более длинном измерении). Вы не можете растягиваться, чтобы соответствовать ширине и высоте без обрезки или растяжения непропорционально.
РЕДАКТИРОВАТЬ: Ладно, я думаю, что теперь я понял. Во-первых, я установил LinearLayout для wrap_content для высоты. Во-вторых, в коде, здесь один из способов сделать это, о котором я могу думать. Возможно, есть и другой способ сделать это, сначала получив размеры экрана, а затем сделав createScaledBitmap
новыми измерениями, а затем установив фоновый ресурс.
final ImageView newsImage = (ImageView)findViewById(R.id.news_image);
//get details on resolution from the display
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
//going to set what happens as the layout happens
newsImage.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
int oldHeight, oldWidth, newHeight, newWidth;
//we want the new width to be as wide as the screen
newWidth = metrics.widthPixels;
oldHeight = newsImage.getDrawable().getIntrinsicHeight();
oldWidth = newsImage.getDrawable().getIntrinsicWidth();
//keeping the aspect ratio, the new height should be w1/h1 = w2/h2
newHeight = Math.floor((oldHeight * newWidth) / oldWidth);
LinearLayout.LayoutParams params =
(LinearLayout.LayoutParams)newsImage.getLayoutParams();
params.height = newHeight;
params.width = newWidth;
newsImage.setLayoutParams(params);
newsImage.setScaleType(ScaleType.CENTER);
newsImage.invalidate();
newsImage.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
}
Ответ 4
Я googled везде и не мог найти решение.
Вот что я сделал, это сработало для меня и с просмотром прокрутки.
XML файл:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<ImageView
android:id="@+id/manga_page_image"
android:layout_width="match_parent"
android:layout_height="0dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
</ScrollView>
Ответ 5
Пробовали ли вы программно настроить его с помощью ImageView.setScaleType()
?
setAdjustViewBounds( false )
также может помочь.
Изменить: извините, я неправильно прочитал вопрос. Несмотря на это, setAdjustViewBounds()
все равно может помочь. Никогда не использовал его.
Ответ 6
Я хочу показать эти изображения в полном объеме ширина устройства.
Это просто. У вас просто неправильные настройки полей. Удалите эти строки, и ваше изображение будет отображаться в полной ширине устройства:
android:layout_marginLeft="18dip"
android:layout_marginRight="18dip"
Ответ 7
Я больше не вижу изображения, и вопрос старый, но на случай, если кто-то найдет это и будет иметь такую же проблему. Не лучше ли было бы получить float screenWidth = getResources().getDisplayMetrics().widthPixels
и программно настроить ImageView LayoutParamters для масштабирования изображения до screenWidth
. Просто идея!
Ответ 8
удается достичь того, чего я хотел, что, надеюсь, совпадает с вашей целью:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pgviewer);
ImageView PgContainer = (ImageView)findViewById(R.id.imageView1);
String Page = String.valueOf(getIntent().getExtras().getInt("Page"));
try {
PgContainer.setImageBitmap(getBitmapFromAsset(Page));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PgContainer.setScaleType(ScaleType.FIT_CENTER);
PgContainer.scrollTo(0, 0);
PgContainer.setScrollBarStyle(0);
}
затем масштабировать растровое изображение:
private Bitmap getBitmapFromAsset(String strName) throws IOException
{
AssetManager assetManager = getAssets();
InputStream istr = assetManager.open(strName+".png");
Bitmap bitmap = BitmapFactory.decodeStream(istr);
float screenWidth = getResources().getDisplayMetrics().widthPixels;
int ih=bitmap.getHeight();
int iw=bitmap.getWidth();
float scalefactor = screenWidth/iw;
//w = 480, h=~
//int newh = bitmap.getHeight()/bitmap.getWidth();
return android.graphics.Bitmap.createScaledBitmap(bitmap, (int)(iw*scalefactor), (int)(ih*scalefactor), true);
//return bitmap;
}
Ответ 9
То, что я использовал для масштабирования ImageView с разрешением устройства, задает свойства относительно родителя. Так как размер родительского размера изменяется, размер элементов также будет масштабироваться.
Вот пример моего activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.csci567.singleimagerequest.MainActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/image_display"
android:layout_marginBottom="100dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_centerHorizontal="true"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Upload Image"
android:id="@+id/upload_button"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="22dp" />
</RelativeLayout
Вы можете поместить больше элементов, отрегулировав поля.