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.