Jak wdrożyć androida: tło, które się nie rozciąga?


100

Znalazłem świetny wątek opisujący, jak "zjeść ciasto i też je mieć", tj. Użyj obrazka Buttonzamiast ImageButton(co nie pozwala SetText(), zmiana rozmiaru itp.).

Osiąga się to za pomocą atrybutu View:

android:background="@drawable/bgimage"

Jedynym problemem jest to, że rozciąga obraz, aby dopasować go do rozmiaru przycisku.

Oprócz zakodowania stałego rozmiaru przycisku (w pikselach!), Czy istnieje sposób, aby powiedzieć Androidowi, aby w ogóle nie rozciągał obrazu tła i albo go przycinał, ani nie wypełniał?

Odpowiedzi:


29

Powinieneś użyć ImageView, jeśli nie chcesz, aby się rozciągał. Obrazy tła będą zawsze rozciągane, aby pasowały do ​​widoku. Musisz ustawić go jako Drawable, aby wymusić aspekt obrazu na obiekcie.

W przeciwnym razie, jeśli trzymasz się idei przycisku, będziesz musiał wymusić skalowanie w przycisku, aby zapobiec rozciągnięciu obrazu.

Kod:

onCreate(Bundle bundle) {
  // Set content layout, etc up here

  // Now adjust button sizes
  Button b = (Button) findViewById(R.id.somebutton);
  int someDimension = 50; //50pixels
  b.setWidth(someDimension);
  b.setHeight(someDimension);
}

1
Dzięki + 1. ImageViewwygląda interesująco. Zauważyłem, że ma atrybut, który nie jest w Button: android:cropToPadding. Nie mam nic przeciwko używaniu zamiast tego ImageView, o ile ma setOnClickListener()- co robi. Co stracę, przechodząc z Buttonna ImageView?
— ef2011

1
Przy okazji, drugie rozwiązanie, które zasugerowałeś, nadal rozciąga obraz.
— ef2011

Skończyło się na tym, że użyłem stałego rozmiaru przycisku (w pikselach!), Ale przyjmuję twoją odpowiedź, ponieważ pierwsza sugestia wygląda na działające alternatywne rozwiązanie.
— ef2011

1
@ ef2011 W przypadku ImageView, nie ustawiaj go jako obrazu tła, musisz ustawić go jako a, setDrawableResourcea następnie upewnić się, że setAdjustViewBoundsjest ustawiony na true
— Dr J

9
Głos za kiepskim rozwiązaniem. Prawidłowe rozwiązanie tutaj: stackoverflow.com/a/9362168/145046
— Aleks N.

261

Możesz utworzyć bitmapę xml i użyć jej jako tła dla widoku. Aby zapobiec rozciągnięciu, możesz określić android:gravityatrybut.

na przykład:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/dvdr"
    android:tileMode="disabled" android:gravity="top" >
</bitmap>

Istnieje wiele opcji, których możesz użyć, aby dostosować renderowanie obrazu

http://developer.android.com/guide/topics/resources/drawable-resource.html#Bitmap


3
Korzystanie z ImageViews to obejście, które nie zawsze jest możliwą opcją - uważam, że jest to właściwe rozwiązanie :)
— JakeP,

3
Ustawiam tło w czasie wykonywania. Czy jest jakieś rozwiązanie do tworzenia bitmap w czasie wykonywania?
— Vivek Kumar Srivastava

1
dla mnie było to najlepsze rozwiązanie, ale usunięcie atrybutu „gravity”, co powoduje, że odpowiada on domyślnej wartości „fill”. Umożliwi to zmianę rozmiaru obrazu w celu dopasowania go do ekranu. Przeczytaj łącze @Santosh, aby uzyskać więcej informacji. Dzięki!
— Hugo,

12
Widzę tylko jeden problem z tym podejściem. Jeśli źródło do rysowania jest już większe niż kontener, spowoduje to przycięcie obrazu (na podstawie grawitacji) zamiast zmiany jego rozmiaru, zachowując proporcje, aby dopasować się do kontenera.
— Shashwat Black,

1
Teraz wydaje się nieco przestarzały. Działa to tylko w przypadku map bitowych i nie działa w przypadku rysunków Vector.
— The_Sympathizer

25

Po prostu użycie ImageButtonzamiast Buttonrozwiązuje problem.

<ImageButton android:layout_width="30dp"
             android:layout_height="30dp"
             android:src="@drawable/bgimage" />

i możesz ustawić

android:background="@null"

aby usunąć tło przycisku, jeśli chcesz.

Szybka naprawa !! :-)


1
A następnie ustaw obraz za pomocą metody setImageResource () ... która zadziałała.
— arlomedia

chciałem mieć zarówno obraz, jak i kolor tła w przycisku ... to działało jak urok
— Abhishek Chauhan

U mnie działa dokładniej (mam na myśli - na przykład „layout_centerVertical”).
— Maxim Firsoff

12

Używam ImageView w RelativeLayout, który nakłada się z moim normalnym układem. Nie jest wymagany kod. Zmienia rozmiar obrazu do pełnej wysokości ekranu (lub innego używanego układu), a następnie przycina obraz w lewo i w prawo, aby dopasować go do szerokości. W moim przypadku, jeśli użytkownik obróci ekran, obraz może być odrobinę za mały. Dlatego używam match_parent, co spowoduje rozciągnięcie obrazu, jeśli jest za mały.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/main_backgroundImage"
        android:layout_width="match_parent"
        //comment: Stretches picture in the width if too small. Use "wrap_content" does not stretch, but leaves space

        android:layout_height="match_parent"
        //in my case I always want the height filled

        android:layout_alignParentTop="true"
        android:scaleType="centerCrop"
        //will crop picture left and right, so it fits in height and keeps aspect ratio

        android:contentDescription="@string/image"
        android:src="@drawable/your_image" />

    <LinearLayout
        android:id="@+id/main_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    </LinearLayout>

</RelativeLayout>

W rzeczywistości jest to znacznie łatwiejsze rozwiązanie problemu, który nie powinien istnieć
— Ákos Nikházy

6

Miałem ten sam problem: zamiast oryginalnego obrazu powinieneś używać tylko 9-poprawkowego obrazu (.9.png).

Serge


5

Użyj draw9patch ... zawartego w narzędziach SDK Android Studio. Możesz zdefiniować rozciągliwe obszary obrazu. Ważne części są ograniczone, a obraz nie wygląda na wypaczony. Dobre demo na dra9patch jest TUTAJ

Użyj draw9patch, aby zmienić istniejący plik splash.png na new_splash.9.png, przeciągnij new_splash.9.png do folderu projektu drawable-hdpi, upewnij się, że plik AndroidManifest i styles.xml są prawidłowe, jak poniżej:

AndroidManifest.xml:

<application
...
        android:theme="@style/splashScreenStyle"
>

styles.xml:

<style name="splashScreenStyle" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowBackground">@drawable/new_splash</item>
</style>

3

Miałem obraz w tle, nie duży, ale o dziwnych wymiarach - stąd rozciąganie i kiepska wydajność. Stworzyłem metodę z parametrami Context, View i identyfikatorem do rysowania (int), który będzie pasował do rozmiaru ekranu urządzenia. Użyj tego np. W Fragments onCreateView, aby ustawić tło.

public void setBackground(Context context, View view, int drawableId){
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),drawableId);

    bitmap = Bitmap.createScaledBitmap(bitmap, Resources.getSystem().
             getDisplayMetrics().widthPixels,
             Resources.getSystem().getDisplayMetrics().heightPixels,
             true);

    BitmapDrawable bitmapDrawable = new BitmapDrawable(context.getResources(), 
                                    bitmap);

    view.setBackground(bitmapDrawable);
}

1

Oto wersja odpowiedzi Santosha na przyciski utworzone programowo, bez potrzeby osobnej konfiguracji XML:

Button button = new Button(getContext());
Bitmap backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_button);
BitmapDrawable backgroundDrawable = new BitmapDrawable(getResources(), backgroundBitmap);
backgroundDrawable.setGravity(Gravity.CENTER); // also LEFT, CENTER_VERTICAL, etc.
backgroundDrawable.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_ATOP));
button.setBackground(backgroundDrawable);

Dodałem linię ColorFilter, ponieważ działa ona trochę inaczej niż przyciski z normalnym obrazem tła.


1

Można używać FrameLayoutze związkiem ImageViewjako pierwsze dziecko, potem normalnym układzie jak drugie dziecko:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <ImageView
        android:id="@+id/background_image_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/your_drawable"/>

  <LinearLayout
        android:id="@+id/your_actual_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

  </LinearLayout>

</FrameLayout>

0

Kluczem jest ustawienie elementu do rysowania jako obrazu przycisku, a nie tła. Lubię to:

rb.setButtonDrawable(R.drawable.whatever_drawable);

Jest to metoda CompoundButton, ale nie Button.
— arlomedia

0

Czy można użyć zwykłego ImageView w swoim xml i uczynić go klikalnym (android: clickable = "true")? Jako źródło wystarczy użyć tylko obrazu, który ma kształt przycisku, czyli zaokrąglone rogi.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.