Масштабирование 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, но который также устанавливает пропорциональную высоту для изображения, чтобы я мог видеть все это, а не только часть изображения.

Edit потому что я знаю, что я путаю вас с моим "странным" квестингом.

Я хочу показать вам изображения. Это то, что я получаю в данный момент с моим макетом. Я хочу заполнить всю серую область, масштабируя изображение настолько большим, насколько это необходимо. Как я могу это сделать?

Когда Я установите ScaleType to CENTER_CROP Я понимаю это

но это не то, что я хочу, потому что вы не видите весь образ только часть из центра.

и это то, что я хочу, чтобы это быть:

надеюсь, это поможет вам понять, чего я пытаюсь достичь. Кто-нибудь знает, как это сделать?

Edit 2:

это может выглядеть странно и немного запутанно, что я пытаюсь отображение изображения, которое больше по высоте, чем размер экрана, но так как я использую ScrollView в моем примере макета это должно быть в порядке, и пользователь может прокручивать, если он хочет увидеть не отображаемую область.

надеюсь, это поможет понять, что я пытаюсь сделать.

9 ответов


Я старалась каждый ScaleType в своем ImageView С fill_parent и wrap_content но никто из них не работал. Я также попробовал все, что нашел в Google, но ничего не сработало для меня, поэтому придумал что-то самостоятельно.

было ясно, что ImageView не масштабирует мое изображение, как я хотел масштабироваться, поэтому мне пришлось масштабировать его самостоятельно. После масштабирования растрового изображения я бы установил новое растровое изображение в качестве источника изображения в 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 class

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

}

если есть лучший или более точный способ выполнить то же масштабирование пожалуйста, дайте мне знать потому что я не могу поверить, что такую тривиальную вещь так трудно выполнить.

Я действительно надеюсь увидеть лучший способ сделать это.

спасибо для чтения.


самый простой способ-добавить android: adjustViewBounds= " true "в ImageView и установить тип шкалы в"fitCenter"


немного смущен тем, что вы ищете, точно. Если вы масштабируете, чтобы соответствовать экрану, у вас есть три варианта, два из которых жизнеспособны, если вы сохраняете пропорции. Вы можете использовать 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);
        }
    }
}

Я везде гуглил и не мог найти решение. Вот что я сделал, это сработало для меня и с видом прокрутки.

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>

вы пытались установить его программно через ImageView.setScaleType()?

setAdjustViewBounds( false ) также может помочь.

Edit: извините, я неправильно прочитал вопрос. Несмотря ни на что,setAdjustViewBounds() еще может помочь. Но никогда им не пользовался.


Я хочу показать эти изображения в полном ширина устройства.

Это просто. У вас просто неверные настройки маржи. Удалите эти строки, и ваше изображение будет отображаться в полной ширине устройства:

android:layout_marginLeft="18dip"
android:layout_marginRight="18dip" 

Я больше не вижу изображений, и вопрос старый, но на всякий случай кто-то еще находит это и имеет ту же проблему. Не лучше ли просто получить float screenWidth = getResources().getDisplayMetrics().widthPixels и установите LayoutParamters ImageView программно для масштабирования изображения до screenWidth. Просто идея !!


управлять, чтобы достичь того, что я хотел, что, надеюсь, так же, как ваша цель:

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

то, что я использовал для масштабирования 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

вы можете поместить больше элементов путем корректировки прибыли.