Jak programowo zaokrąglać rogi i ustawiać losowe kolory tła

114

Chciałbym zaokrąglić rogi widoku, a także zmienić kolor widoku na podstawie zawartości w czasie wykonywania.

TextView v = new TextView(context);
v.setText(tagsList.get(i));
if(i%2 == 0){
    v.setBackgroundColor(Color.RED);
}else{
    v.setBackgroundColor(Color.BLUE);
}

v.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
v.setPadding(twoDP, twoDP, twoDP, twoDP);               
v.setBackgroundResource(R.drawable.tags_rounded_corners);

Miałem nadzieję, że ustawienie do narysowania i koloru się pokryje, ale tak się nie dzieje. Niezależnie od tego, który wykonam jako drugi, powstanie tło.

Czy istnieje sposób na programowe utworzenie tego widoku, pamiętając, że kolor tła zostanie określony dopiero w czasie wykonywania?

edycja: Zamieniam się teraz między czerwonym i niebieskim tylko do testów. Później kolor będzie wybierany przez użytkownika.

edytować:

tags_rounded_corners.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <corners 
         android:bottomRightRadius="2dp" 
         android:bottomLeftRadius="2dp" 
         android:topLeftRadius="2dp" 
         android:topRightRadius="2dp"/>
</shape>
John Moffitt
źródło
Oczywiście kolor tła i obraz tła zastępują się nawzajem. Co próbujesz osiągnąć? Co to jest tags_rounded_corners?
Alex MDC
Czy mógłbyś pokazać więcej kodów? Wygląda dobrze, więc zastanawiam się, czy możesz użyć czegoś w rodzaju listView lub ponownie użyć istniejącego widoku tekstowego.
Chansuk

Odpowiedzi:

211

Zamiast tego setBackgroundColorpobierz tło do rysowania i ustaw jego kolor:

v.setBackgroundResource(R.drawable.tags_rounded_corners);

GradientDrawable drawable = (GradientDrawable) v.getBackground();
if (i % 2 == 0) {
  drawable.setColor(Color.RED);
} else {
  drawable.setColor(Color.BLUE);
}

Możesz także zdefiniować dopełnienie w tags_rounded_corners.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
  <corners android:radius="4dp" />
  <padding
    android:top="2dp"
    android:left="2dp"
    android:bottom="2dp"
    android:right="2dp" />
</shape> 
chiuki
źródło
Perect answe! działało również z strockiem, ale czy możemy to zrobić używając czegoś takiego jak colorDrawable = resources.getDrawable (R.drawable.x_sd_circle); colorDrawable.setColorFilter (color, PorterDuff.Mode.SRC_ATOP); jeśli nie mamy granicy. Ale w przypadku obramowania możesz dać mi znać PorterDuff.Mode, aby kolor obrysu się nie zmienił
Akhil Dad
Jak dodać kolor tła również przez XML?
Lenin Raj Rajasekaran
2
Jeśli „v” jest TextView, to v.getBackground () będzie rzutować „java.lang.ClassCastException: android.graphics.drawable.StateListDrawable nie może być rzutowany na android.graphics.drawable.GradientDrawable” Czy to naprawdę działało w '13?
sonavolob
@sonavolob masz rację. daje ClassCastException
Adnan
Idealne rozwiązanie! Dziękuję Ci!
Bot
124

Całkowicie programowe podejście do ustawiania zaokrąglonych rogów i dodawania losowego koloru tła do widoku. Nie testowałem kodu, ale masz pomysł.

 GradientDrawable shape =  new GradientDrawable();
 shape.setCornerRadius( 8 );

 // add some color
 // You can add your random color generator here
 // and set color
 if (i % 2 == 0) {
  shape.setColor(Color.RED);
 } else {
  shape.setColor(Color.BLUE);
 }

 // now find your view and add background to it
 View view = (LinearLayout) findViewById( R.id.my_view );
 view.setBackground(shape);

Tutaj używamy gradientu do rysowania, abyśmy mogli z niego skorzystać, GradientDrawable#setCornerRadiusponieważ ShapeDrawableNIE zapewnia żadnej takiej metody.

Jaydeep W.
źródło
13
shape.setCornerRadii (rogi); jego bardzo przydatne
umesh
14
Rozważ użycie PaintDrawablezamiast GradientDrawable. Obsługuje zaokrąglone rogi i tylko jeden kolor, który wydaje się być bardziej odpowiedni niż gradient.
Cimlman
2
To działa dobrze! Używam go w Xamarinie. var pd = new PaintDrawable(BackgroundColor); pd.SetCornerRadius(15); myView.Background = pd;
Pierre
Niezłe szybkie rozwiązanie, ale pamiętaj, że wymaga API Minimum Level 16
The Unknown Dev
jak ustawić promień narożnika tylko z jednej strony?
Anonymous-E
10

Myślę, że najszybszym sposobem na to jest:

GradientDrawable gradientDrawable = new GradientDrawable(
            GradientDrawable.Orientation.TOP_BOTTOM, //set a gradient direction 
            new int[] {0xFF757775,0xFF151515}); //set the color of gradient
gradientDrawable.setCornerRadius(10f); //set corner radius

//Apply background to your view
View view = (RelativeLayout) findViewById( R.id.my_view );
if(Build.VERSION.SDK_INT>=16)
     view.setBackground(gradientDrawable);
else view.setBackgroundDrawable(gradientDrawable);    
Nolesh
źródło
9

Możesz to lepiej osiągnąć, używając DrawableCompat w następujący sposób:

Drawable backgroundDrawable = view.getBackground();             
DrawableCompat.setTint(backgroundDrawable, newColor);
Alécio Carvalho
źródło
5

Jeśli nie masz udaru, możesz użyć

colorDrawable = resources.getDrawable(R.drawable.x_sd_circle); 

colorDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);

ale to również zmieni kolor obrysu

Achil tato
źródło
39
Chciałem tego użyć, ale mam udar.
Tim Malseed
2

Oto przykład z użyciem rozszerzenia. Zakłada się, że widok ma taką samą szerokość i wysokość.

Aby uzyskać rozmiar widoku, należy użyć odbiornika zmian układu. Wtedy możesz po prostu nazwać to w takim widokumyView.setRoundedBackground(Color.WHITE)

fun View.setRoundedBackground(@ColorInt color: Int) {
    addOnLayoutChangeListener(object: View.OnLayoutChangeListener {
        override fun onLayoutChange(v: View?, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) {

            val shape = GradientDrawable()
            shape.cornerRadius = measuredHeight / 2f
            shape.setColor(color)

            background = shape

            removeOnLayoutChangeListener(this)
        }
    })
}
Markymark
źródło
1

Możesz dynamicznie zmieniać kolor dowolnych elementów (układ, widok tekstu). Wypróbuj poniższy kod, aby programowo ustawić kolor w układzie

w pliku activity.java


String quote_bg_color = "#FFC107"
quoteContainer= (LinearLayout)view.findViewById(R.id.id_quotecontainer);
quoteContainer.setBackgroundResource(R.drawable.layout_round);
GradientDrawable drawable = (GradientDrawable) quoteContainer.getBackground();
drawable.setColor(Color.parseColor(quote_bg_color));

utwórz layout_round.xml w folderze do rysowania

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/colorPrimaryLight"/>
    <stroke android:width="0dp" android:color="#B1BCBE" />
    <corners android:radius="10dp"/>
    <padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>

układ w pliku activity.xml

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

----other components---

</LinearLayout>

namiętni ewolucje
źródło
1

Kopiowanie komentarza @ cimlman do odpowiedzi najwyższego poziomu dla lepszej widoczności:

PaintDrawable(Color.CYAN).apply {
  setCornerRadius(24f)
}

FYI: ShapeDrawable(i jego podtyp, PaintDrawable) używa domyślnej wewnętrznej szerokości i wysokości 0. Jeśli rysowany element nie pojawia się w Twoim przypadku, może być konieczne ręczne ustawienie wymiarów:

PaintDrawable(Color.CYAN).apply {
  intrinsicWidth = -1
  intrinsicHeight = -1
  setCornerRadius(24f)
}

-1jest magiczną stałą, która wskazuje, że Drawable nie ma własnej wewnętrznej szerokości i wysokości ( Źródło ).

Saket
źródło