How to set random background for cardview? - android

I currently have an Android recyclerview and a list item for it. In the list item is a cardview for my views. I want to have random backgrounds for each card list this one:
my cards now have a solid background and I search every where and used any code but couldn't find an example for view like example.
My list item:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
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:id="#+id/card_view_lead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardCornerRadius="10dp"
app:cardPreventCornerOverlap="false">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/style_lead"
android:padding="7dp">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="#android:color/transparent"
android:contentDescription="#string/option"
android:src="#drawable/ic_option"
android:tint="#android:color/white" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/large_margin"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.makeramen.roundedimageview.RoundedImageView
android:id="#+id/lead_img"
android:layout_width="40dp"
android:layout_height="40dp"
android:contentDescription="#string/test_pic"
app:riv_border_color="#color/colorPrimary"
app:riv_border_width="0.1dp"
app:riv_corner_radius="100dp"
tools:src="#drawable/pic_1" />
<TextView
android:id="#+id/lead_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="#dimen/standard_margin"
android:layout_toRightOf="#id/lead_img"
android:textColor="#android:color/white"
android:textSize="#dimen/large_font_size"
tools:text="#string/test_name" />
</RelativeLayout>
<TextView
android:id="#+id/lead_city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/standard_margin"
android:layout_marginTop="16dp"
android:textColor="#android:color/white"
android:textSize="#dimen/large_font_size"
tools:text="#string/test_city" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/standard_margin">
<TextView
android:id="#+id/lead_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textColor="#android:color/white"
android:textSize="#dimen/large_font_size"
tools:text="30$" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/large_margin"
android:layout_marginTop="16dp"
android:layout_toRightOf="#id/lead_price"
android:text="#string/per_hour"
android:textColor="#android:color/white"
android:textSize="#dimen/large_font_size" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginTop="16dp">
<TextView
android:id="#+id/with"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/standard_margin"
android:text="#string/with"
android:textColor="#android:color/white"
android:textSize="#dimen/large_font_size" />
<TextView
android:id="#+id/lead_vehicle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_toRightOf="#id/with"
android:textColor="#android:color/white"
android:textSize="#dimen/large_font_size"
tools:text="#string/car" />
<ImageView
android:id="#+id/lead_vehicle_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_toRightOf="#id/lead_vehicle"
android:contentDescription="#string/car_img"
tools:src="#drawable/ic_car" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>

You can generate random colors each time you put a new item in the adapter list
See this
Since you only provided the xml part, I am assuming you have a model where you store the information to display. You can add another property "color" where you can store the random color for each item, and set in on your onBindViewHolder method

CardView cardView = (CardView)findViewById(R.id.card_view_lead);
cardView.setCardBackgroundColor(getRandomColorCode());
public int getRandomColorCode(){
Random random = new Random();
return Color.argb(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));
}

CardView card = (CardView)findViewById(R.id.card_view_lead);
in your onbindview holder
Random rnd = new Random();
currentColor = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
holder.card.setCardBackgroundColor(currentColor);

Create Array in res/values/colour like this
<array name="note_neutral_colors">
<item>#9E9E9E</item>
<item>#455A64</item>
<item>#607D8B</item>
</array>
<array name="note_accent_colors">
<item>#039BE5</item>
<item>#3D51B3</item>
<item>#689f38</item>
<item>#FD7044</item>
</array>
In Your Adapter Class
holder.cardView.setCardBackgroundColor(noticeModel.getColor());
Model Class
//Variable
int color;
//Cunstructor
this.color=color;
///and generate Getter Setter
Do this Your Main Class.java
private static int getRandomColor(Context context) {
int[] colors;
if (Math.random() >= 0.6) {
colors = context.getResources().getIntArray(R.array.note_accent_colors);
} else {
colors = context.getResources().getIntArray(R.array.note_neutral_colors);
}
return colors[((int) (Math.random() * colors.length))];
}
call this method with string request like this
yourModel = new Your_Model(data1,data2,data3,getRandomColor(YourActivity.this));

You need to write some logic to produce random colors and then use it like
CardView card = (CardView)findViewById(R.id.card);
card.setCardBackgroundColor(color);
To produce random colors, solutions are already available on Stack Overflow, please have a look at this link.

Normally we can do like this,
Colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="blue" type="color">#FF33B5E5</item>
<item name="purple" type="color">#FFAA66CC</item>
<item name="green" type="color">#FF99CC00</item>
<item name="orange" type="color">#FFFFBB33</item>
<item name="red" type="color">#FFFF4444</item>
<item name="darkblue" type="color">#FF0099CC</item>
<item name="darkpurple" type="color">#FF9933CC</item>
<item name="darkgreen" type="color">#FF669900</item>
<item name="darkorange" type="color">#FFFF8800</item>
<item name="darkred" type="color">#FFCC0000</item>
<integer-array name="androidcolors">
<item>#color/blue</item>
<item>#color/purple</item>
<item>#color/green</item>
<item>#color/orange</item>
<item>#color/red</item>
<item>#color/darkblue</item>
<item>#color/darkpurple</item>
<item>#color/darkgreen</item>
<item>#color/darkorange</item>
<item>#color/darkred</item>
</integer-array>
</resources>
And do this in your onCreateView(),
CardView card_view_lead;
card_view_lead= (CardView) findViewById(R.id.card_view_lead);
int[] androidColors = getResources().getIntArray(R.array.androidcolors);
int randomAndroidColor = androidColors[new Random().nextInt(androidColors.length)];
card_view_lead.setBackgroundColor(randomAndroidColor);
If you don't want to use color array then you can use like this in your onCreateView() or onCreate(),
mCardViewTop.setCardBackgroundColor(getRandomColor());
public static int getRandomColor() {
Random rnd = new Random();
return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
}

Related

Weird Band Color on the Selected Item's Surface

I have a weird issue when the selection is highlighted in a recycler view. This problem occurs as of API level 30 and above as per my tests. I did not observed any problem like this within the lower API levels, at least APIs below 28.
A screenshot of API 30
A screenshot of API 27
This screenshot is taken from a Motorola G5S Plus which running Android 11
This one is taken from General Mobile 6 which is running Android 8.1.0
Both phones was running the same version of the application. As you can see in the left picture there is a band within the highlighted area. In this area there are 2 discrete TextViews and some gap between them.
Let's take a look at the highlighting color xml named him_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.4" android:color="?attr/colorSecondaryVariant" android:state_activated="true"/>
<item android:color="?attr/colorSurface"/>
</selector>
The following xml is the list item design.
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<import type="android.view.View"/>
<import type="com.himtec.himtec_kontrol.ui.viewmodel.AygitListelemeVM"/>
<variable name="kipSurukle" type="boolean"/>
<variable name="gozde" type="boolean"/>
</data>
<com.himtec.himtec_kontrol.ui.AygitMaterialCardView
android:id="#+id/amcv_aygit"
style="#style/Widget.Himtec.MaterialCardView.Elevated.RoundCorners.Large"
android:layout_width="match_parent"
android:layout_height="#dimen/him_card_device_height"
android:layout_margin="#dimen/him_card_device_margin"
android:checkable="false"
android:clickable="true"
android:clipChildren="true"
android:clipToPadding="false"
android:focusable="true"
app:cardBackgroundColor="#color/him_selector" <!-- I use that color selector as card's background color to highlight it when it is selected -->
app:cardMaxElevation="#dimen/him_card_drag_elevation"
app:cardPreventCornerOverlap="false">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/cl_aygit"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:duplicateParentState="true">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="?attr/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#id/gl_aygit_model_icerik_hiza"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.imageview.ShapeableImageView
android:id="#+id/iv_nokta_simge"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="#string/cd_aygitSimgesi"
android:duplicateParentState="true"
android:scaleType="center"
android:tint="?attr/colorSurface"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/gl_aygit_model_icerik_hiza"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/him_aygit_simge_selector"
tools:srcCompat="#drawable/him_aygit_simge_selector" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/tv_nokta_ad"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:gravity="center_vertical"
android:padding="2dp"
android:singleLine="true"
android:textAlignment="gravity"
android:textAppearance="#style/TextAppearance.MaterialComponents.Body1"
app:layout_constraintBottom_toTopOf="#+id/mtv_eklenme"
app:layout_constraintEnd_toStartOf="#+id/tus_sirala"
app:layout_constraintStart_toStartOf="#+id/gl_aygit_model_icerik_hiza"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginEnd="#dimen/him_card_content_padding_8dp" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/mtv_eklenme"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:gravity="center_vertical"
android:padding="2dp"
android:singleLine="true"
android:text="#string/sc_eklendi"
android:textAlignment="gravity"
android:textSize="12sp"
app:layout_constraintBottom_toTopOf="#+id/mtv_son_baglanma"
app:layout_constraintStart_toStartOf="#+id/gl_aygit_model_icerik_hiza"
app:layout_constraintTop_toBottomOf="#+id/tv_nokta_ad"
app:layout_constraintVertical_chainStyle="packed" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/mtv_eklenme_deger"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:gravity="center_vertical"
android:padding="2dp"
android:singleLine="true"
android:textAlignment="gravity"
android:textSize="12sp"
app:layout_constraintBaseline_toBaselineOf="#+id/mtv_eklenme"
app:layout_constraintEnd_toStartOf="#+id/tus_sirala"
app:layout_constraintStart_toEndOf="#id/br_aygit_model_alt_bilgi_baslik"
app:layout_goneMarginEnd="#dimen/him_card_content_padding_8dp" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/mtv_son_baglanma"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:gravity="center_vertical"
android:padding="2dp"
android:singleLine="true"
android:text="#string/sc_sonBaglanti"
android:textAlignment="gravity"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="#+id/gl_aygit_model_icerik_hiza"
app:layout_constraintTop_toBottomOf="#+id/mtv_eklenme" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/mtv_son_baglanma_deger"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:gravity="center_vertical"
android:padding="2dp"
android:singleLine="true"
android:textAlignment="gravity"
android:textSize="12sp"
app:layout_constraintBaseline_toBaselineOf="#+id/mtv_son_baglanma"
app:layout_constraintEnd_toStartOf="#+id/tus_sirala"
app:layout_constraintStart_toEndOf="#id/br_aygit_model_alt_bilgi_baslik"
app:layout_goneMarginEnd="#dimen/him_card_content_padding_8dp" />
<Button
android:id="#+id/tus_sirala"
style="#style/Widget.Himtec.Button.TextButton"
android:layout_width="36dp"
android:layout_height="0dp"
android:visibility="#{kipSurukle ? View.VISIBLE : View.GONE}"
app:icon="#drawable/him_surukle_24"
app:iconPadding="0dp"
app:iconSize="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Barrier
android:id="#+id/br_aygit_model_alt_bilgi_baslik"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="mtv_eklenme,mtv_son_baglanma"
tools:layout_editor_absoluteX="169dp" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/gl_aygit_model_icerik_hiza"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="82dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.himtec.himtec_kontrol.ui.AygitMaterialCardView>
</layout>
In both phones the same item xml and color exist. The highlighting is made by activating the AygitMaterialcardView which is a custom class that extends MaterialCardView. The activation is made by setting the View.setActivated() method to true.
The custom card implementation:
public class AygitMaterialCardView extends MaterialCardView {
private static final String E = AygitMaterialCardView.class.getSimpleName();
/* Uygulamaya özel tanımlanan durumlar */
private static final int DURUM_HICBIRI = 0;
private static final int DURUM_GOZDE = 1;
private static final int DURUM_SURUKLE = 2;
private static final int[] HIM_AYGIT_DURUMLAR = {
R.attr.durum_hicbiri,
R.attr.durum_gozde,
R.attr.durum_surukleme
};
private boolean gozde;
private boolean surukleme;
private int durum;
public AygitMaterialCardView(Context context) {
super(context);
}
/* XML kaynaktan ilklenirken bu oluşturucu çağrılıyor */
public AygitMaterialCardView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected int[] onCreateDrawableState(int extraSpace) {
final int[] drawableStates = super.onCreateDrawableState(extraSpace +1);
// Fazladan gözde durumunu ekleyeceğiz
if(gozde) {
int[] d = { HIM_AYGIT_DURUMLAR[DURUM_GOZDE] };
mergeDrawableStates(drawableStates, d);
}
if(surukleme) {
int[] d = { HIM_AYGIT_DURUMLAR[DURUM_SURUKLE] };
mergeDrawableStates(drawableStates, d);
}
return drawableStates;
}
public boolean isGozde() {
return gozde;
}
public void setGozde(boolean gozde) {
if(gozde == this.gozde) return;
this.gozde = gozde;
refreshDrawableState();
invalidate();
requestLayout();
}
public boolean isSurukleme() {
return surukleme;
}
public void setSurukleme(boolean surukleme) {
if(surukleme == this.surukleme) return;
this.surukleme = surukleme;
refreshDrawableState();
invalidate();
requestLayout();
}
}
Attributes to Mike M. for the solution for this matter. Thanks to his guidance that I could see that the cause of the issue was the translucent background color which caused by alpha settings of the selector.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.4" android:color="?attr/colorSecondaryVariant" android:state_activated="true"/>
<item android:color="?attr/colorSurface"/>
</selector>
There are two solutions to get rid of that glitch:
Is to set to elevation of the card to zero and trade-off the shadow.
Is to remove the alpha from the selection color.
Since I didn't want to trade-off the shadow for my design requirements, I decided to get rid of the alpha and make the selection color totally solid.

PopupWindow not shown as expected (preview is ok)

I'm trying to show a full screen popup window from a fragment. I was starting the layout for the screen and it looked as expected in the AS screen preview, but it doesn't when it is executed in a device. Basically, it seems that the paddings are omitted. All of them, the paddings in the root of the layout, in the image view which I put to increase the clickable area, in the text input layout (added by theme).
On the other hand, the animation is not shown in some devices but in emulator is.
Here is the layout file ``:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:background="#color/dark_gray"
android:fitsSystemWindows="true"
android:paddingStart="#dimen/padding_start"
android:paddingTop="#dimen/padding_top"
android:paddingEnd="#dimen/padding_end"
android:paddingBottom="#dimen/padding_bottom">
<ImageView
android:id="#+id/bt_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/grid_size_x2_5"
android:src="#drawable/ic_close"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/tv_title"
style="#style/TextAppearance.Touche.H3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Product"
android:text="Product"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#id/bt_close"
tools:textColorHint="#color/white" />
<Button
android:id="#+id/bt_add_item"
style="#style/TextAppearance.Touche.Button.Primary"
android:layout_width="match_parent"
android:layout_height="#dimen/button_height"
android:text="#string/add_order_add__to_order"
app:layout_constraintBottom_toBottomOf="parent" />
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/ti_quantity"
android:layout_width="#dimen/grid_size_x10"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/grid_size_x6"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/bt_close">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/et_quantity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:lines="1"
android:maxLength="50"
android:paddingStart="#dimen/padding_start"
android:paddingTop="#dimen/padding_top"
android:paddingEnd="#dimen/padding_end"
android:paddingBottom="#dimen/padding_bottom"
android:text="0" />
</com.google.android.material.textfield.TextInputLayout>
<ImageButton
android:id="#+id/bt_less"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null"
android:paddingStart="#dimen/padding_start"
android:paddingTop="#dimen/padding_top"
android:paddingEnd="#dimen/padding_end"
android:paddingBottom="#dimen/padding_bottom"
android:src="#drawable/ic_less_selector"
app:layout_constraintBottom_toBottomOf="#id/ti_quantity"
app:layout_constraintEnd_toStartOf="#id/ti_quantity"
app:layout_constraintTop_toTopOf="#id/ti_quantity" />
<ImageButton
android:id="#+id/bt_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null"
android:paddingStart="#dimen/padding_start"
android:paddingTop="#dimen/padding_top"
android:paddingEnd="#dimen/padding_end"
android:paddingBottom="#dimen/padding_bottom"
android:src="#drawable/ic_add_selector"
app:layout_constraintBottom_toBottomOf="#id/ti_quantity"
app:layout_constraintStart_toEndOf="#id/ti_quantity"
app:layout_constraintTop_toTopOf="#id/ti_quantity" />
</androidx.constraintlayout.widget.ConstraintLayout>
And here you have the kotlin code inside a fragment:
context?.let {
val customView: View = (it.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater).inflate(R.layout.popup_add_item, null)
val popupWindow = PopupWindow(it)
popupWindow.contentView = customView
popupWindow.width = LinearLayout.LayoutParams.MATCH_PARENT
popupWindow.height = LinearLayout.LayoutParams.MATCH_PARENT
popupWindow.animationStyle = R.style.popup_window_animation // TODO Not working in some devices
popupWindow.elevation = 5f
popupWindow.showAtLocation(getBinding().rvDiscounts, Gravity.CENTER, 0, 0)
val btClose = customView.findViewById<ImageView>(R.id.bt_close)
val btAddToCart = customView.findViewById<Button>(R.id.bt_add_item)
val btAdd = customView.findViewById<ImageButton>(R.id.bt_add)
val btLess = customView.findViewById<ImageButton>(R.id.bt_less)
val etQuantity = customView.findViewById<TextInputEditText>(R.id.et_quantity)
btClose.setOnClickListener {
popupWindow.dismiss()
}
btAddToCart.setOnClickListener {
// TODO add to cart
popupWindow.dismiss()
}
btAdd.setOnClickListener {
val currentQuantity = etQuantity.text.toString().toInt()
etQuantity.setText(currentQuantity.inc().toString())
}
btLess.setOnClickListener {
val currentQuantity = etQuantity.text.toString().toInt()
if (currentQuantity > 0) etQuantity.setText(currentQuantity.dec().toString())
}
}
And finally the screenshots, the preview and expected first, the shown on the device second:
To the plus and minus button use a android:margin_start="8dp" and android:margin_end="8dp" respectively, to get some space between the button and the TextInputEditText box.
If you wish to center the zero within TextInputEditText then use android:gravity="center"
The #dimen/padding_start values in these might not be acceptable, so just hardcode the values using android:paddingHorizontal="8dp" and android:paddingVertical="8dp".
<style name="AppTheme.FullScreenDialog" parent="Theme.MaterialComponents.Light.Dialog">
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="colorPrimary">#color/colorPrimary</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowBackground">#android:color/white</item>
<item name="actionMenuTextColor">#color/colorAccent</item>
</style>
Use this style while creating your Dialog in the fragment like this :
var fullScreenCameraDialog = Dialog(context, R.style.AppTheme_FullScreenDialog)

multiple hexagon shape buttons

I'm trying to create a design with multiple hexagon shape buttons.I'm able to create a single hexagon button, but in my case i have a list of items which need to be shown in a design pattern like below.
if such list design is possible through RecyclerView that would be much better.
A bit tricky but here is how i solved it.
Have a recyclerView like below
<android.support.v7.widget.RecyclerView
android:id="#+id/hexa_rcv"
android:layout_margin=""#dimen/hexa_dp""
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
make 2 folders inside res "values-sw360dp" and "values-sw400dp". create dimens.xml in both the folders. dimens.xml inside values-sw360dp should have
<resources>
<dimen name="margin_16_dp">16dp</dimen>
<dimen name="hexa_dp">25dp</dimen>
</resources>
dimens.xml inside values-sw400dp should have
<resources>
<dimen name="margin_16_dp">16dp</dimen>
<dimen name="hexa_dp">55dp</dimen>
</resources>
And one item for the recyclerView like below
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tv_1"
android:layout_width="100dp"
android:layout_height="100dp"
android:gravity="center"
android:textColor="#color/white"
android:textSize="18sp"
android:text="ICU_HDW"
android:background="#drawable/hexagon"/>
Next have a get the reference of recyclerView and set GridaLayoutManager with column size as 3. make every 5th item's span size as 2(so that 4th item will have span size 1 and 5th item will have size 2 hence both together will complete the row and next item will be placed in next row)
I have used kotlin here you can convert to java
RecyclerView hexaRcv = (RecyclerView) findViewById(R.id.hexa_rcv);
GridLayoutManager manager = new GridLayoutManager(this, 3);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
int size = 1;
if ((position + 1) % 5 == 0){
size = 2;
}
return size;
}
});
hexaRcv.setLayoutManager(manager);
hexaRcv.setAdapter(new GridAdapter());
Below is the GridAdapter ()
public class GridAdapter extends RecyclerView.Adapter<GridAdapter.HexagonHolder> {
#Override
public GridAdapter.HexagonHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.hexa_tv, parent, false);
return new HexagonHolder(view);
}
#Override
public void onBindViewHolder(GridAdapter.HexagonHolder holder, int position) {
int pos = position + 1;
int topMargin = pxFromDp(holder.textView.getContext(), -17);
int leftMargin = pxFromDp(holder.textView.getContext(), 51); //3 times of 17
GridLayoutManager.LayoutParams param = (GridLayoutManager.LayoutParams) holder.textView.getLayoutParams();
if (pos < 4) {
param.setMargins(0, 0, 0, 0);
} else if ((pos + 1) % 5 == 0 || pos % 5 == 0) {
param.setMargins(leftMargin, topMargin, 0, 0);
} else {
param.setMargins(0, topMargin, 0, 0);
}
holder.textView.setLayoutParams(param);
}
#Override
public int getItemCount() {
return 17;
}
static class HexagonHolder extends RecyclerView.ViewHolder {
TextView textView;
HexagonHolder(View v) {
super(v);
textView = v.findViewById(R.id.tv_1);
}
}
private int pxFromDp(final Context context, final float dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
}
}
for first 3 items no margin. After that all item will have a negative top margin of 75 (i.e. -75px). every 4th and 5th item will not only have top margin of -75 but will also have a left margin of 165.
You can use constant or actually calculate them based on screen width or use dip.
Below is the result
Below is the hexagon.xml save it in drawable folder
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="512dp"
android:height="512dp"
android:viewportWidth="512"
android:viewportHeight="512">
<path
android:fillColor="#148275"
android:pathData="M485.291,129.408l-224-128c-3.285-1.877-7.296-1.877-10.581,0l-224,128c-3.328,1.899-5.376,5.44-5.376,9.259v234.667
c0,3.819,2.048,7.36,5.376,9.259l224,128c1.643,0.939,3.456,1.408,5.291,1.408s3.648-0.469,5.291-1.408l224-128
c3.328-1.899,5.376-5.44,5.376-9.259V138.667C490.667,134.848,488.619,131.307,485.291,129.408z" />
</vector>
You can try something like that. It needs to be improved as the gap between the two lines is not constant depending on the screen size:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<include
layout="#layout/partial_squared"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
partial_squared.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
layout="#layout/partial_first_row"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<include
layout="#layout/partial_second_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/line_height_80" />
</RelativeLayout>
partial_first_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView style="#style/InlinedImageView" />
<ImageView style="#style/InlinedImageView" />
<ImageView style="#style/InlinedImageView" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="horizontal">
<TextView
style="#style/InlinedTextView"
android:text="case 1" />
<TextView
style="#style/InlinedTextView"
android:text="case 2" />
<TextView
style="#style/InlinedTextView"
android:text="case 3" />
</LinearLayout>
</RelativeLayout>
partial_second_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="3">
<Space
android:layout_width="0dp"
android:layout_height="15dp"
android:layout_weight=".5" />
<ImageView style="#style/InlinedImageView" />
<ImageView style="#style/InlinedImageView" />
<Space
android:layout_width="0dp"
android:layout_height="15dp"
android:layout_weight=".5" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="horizontal">
<Space
android:layout_width="0dp"
android:layout_height="15dp"
android:layout_weight=".5" />
<TextView
style="#style/InlinedTextView"
android:text="case 1" />
<TextView
style="#style/InlinedTextView"
android:text="case 2" />
<Space
android:layout_width="0dp"
android:layout_height="15dp"
android:layout_weight=".5" />
</LinearLayout>
</RelativeLayout>
dimens.xml
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="line_height">110dp</dimen>
<dimen name="line_height_80">72dp</dimen>
<dimen name="margin_in_between">2dp</dimen>
</resources>
styles.xml
<style name="InlinedImageView">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">#dimen/line_height</item>
<item name="android:layout_weight">1</item>
<item name="android:src">#drawable/triangle</item>
<item name="android:paddingLeft">#dimen/margin_in_between</item>
<item name="android:paddingRight">#dimen/margin_in_between</item>
</style>
<style name="InlinedTextView">
<item name="android:gravity">center</item>
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">1</item>
</style>
Result

Highlight a pressed card item : using CardView from cardslib

I'm using CardView in a CardListView.
I would like to know how to highlight a card item when it's pressed just like in the "CardsLibDemo Extras" application, precisely in the "Card and Weather List" fragment when you press on a card from the "You may know" list ?
P.S. : I'm using API 15 (Android 4.0.4 Ice Cream sandwich) to test this application.
This is my fragment layout :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- You can customize this layout.
You need to have in your layout a `CardView` with the ID `list_cardId` -->
<it.gmariotti.cardslib.library.view.CardListView
xmlns:card="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/rent_list"
android:foreground="?android:attr/selectableItemBackground"
card:list_card_layout_resourceID="#layout/card_row_layout_rent_list" />
</LinearLayout>
Here is the card_row_layout_rent_list.xml :
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<it.gmariotti.cardslib.library.view.CardView
xmlns:card="http://schemas.android.com/apk/res-auto"
android:id="#+id/list_cardId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card:card_layout_resourceID="#layout/card_layout"
style="#style/list_card.base"/>
</LinearLayout>
Here is the card_layout.xml :
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Card visible layout -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/card_main_layout"
style="#style/card.main_layout">
<it.gmariotti.cardslib.library.view.component.CardThumbnailView
xmlns:card="http://schemas.android.com/apk/res-auto"
style="#style/card_thumbnail_outer_layout"
android:id="#+id/card_thumbnail_layout"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
card:card_thumbnail_layout_resourceID="#layout/card_image" />
<FrameLayout
android:id="#+id/card_main_content_layout"
android:layout_gravity="right"
style="#style/card.content_outer_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<!-- Compound view for Shadow
If you want to customize this element use attr card:card_shadow_layout_resourceID -->
<it.gmariotti.cardslib.library.view.component.CardShadowView
style="#style/card.shadow_outer_layout"
android:id="#+id/card_shadow_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#+id/card_content_expand_layout"
style="#style/card.main_contentExpand"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Here is the card_inner_layout_rent_list.xml :
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- This is the base Inner View inside a CardHeader.
You can customize it with your layout xml file and your CardHeader.
You can popolate your elements with CardHeader#setupInnerViewElements(android.view.ViewGroup, android.view.View) method -->
<TextView
android:id="#+id/textViewPrix"
style="#style/card.header_simple_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginTop="2dp"
android:text="#string/card_txtPrix"
android:textColor="#color/blue"
android:textStyle="bold" />
<TextView
android:id="#+id/textViewAdr"
style="#style/card.expand_simple_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginTop="2dp"
android:text="#string/card_txtAdr"
android:textColor="#color/black"
android:textSize="#dimen/card_expend_simple_title_text_size_16sp"
android:textStyle="bold" />
<TextView
android:id="#+id/textViewType"
style="#style/card.expand_simple_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginTop="2dp"
android:text="#string/card_txtType"
android:textColor="#color/black"
android:textSize="#dimen/card_expand_simple_title_text_size_12sp" />
<TextView
android:id="#+id/textViewSup"
style="#style/card.expand_simple_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginTop="1dp"
android:text="#string/card_txtSup"
android:textColor="#color/black"
android:textSize="#dimen/card_expand_simple_title_text_size_12sp" />
<TextView
android:id="#+id/textViewHonor"
style="#style/card.expand_simple_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginTop="0dp"
android:text="#string/card_txtHonor"
android:textSize="#dimen/card_expand_simple_title_text_size_12sp" />
</LinearLayout>
Here is the card_image.xml :
<?xml version="1.0" encoding="UTF-8"?>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/card_thumbnail_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="1dp"
android:layout_weight="0"
android:layout_gravity="center"
android:contentDescription="#string/imageview_desc"
android:orientation="vertical"/>
Finally, here's where I fill CardList (extracted from the fragment class) :
private void initColorCard() {
int listImages[] = new int[]{R.drawable.angry_1, R.drawable.angry_2,
R.drawable.angry_3, R.drawable.angry_4, R.drawable.angry_5};
ArrayList<Card> cards = new ArrayList<Card>();
for (int i = 0; i<5; i++) {
// Create a Card
ColorCard card = new ColorCard(getActivity());
//Set onClick listener
card.setOnClickListener(new Card.OnCardClickListener() {
#Override
public void onClick(Card card, View view) {
Toast.makeText(getActivity(), "Clickable card : " + card.getCardHeader().getTitle(), Toast.LENGTH_SHORT).show();
}
});
// Create a CardHeader
CardHeader header = new CardHeader(getActivity());
// Add Header to card
header.setTitle("" + i);
card.addCardHeader(header);
CardThumbnail thumb = new CardThumbnail(getActivity());
thumb.setDrawableResource(listImages[i]);
card.addCardThumbnail(thumb);
cards.add(card);
}
CardArrayAdapter mCardArrayAdapter = new CardArrayAdapter(getActivity(), cards);
CardListView listView = (CardListView) getActivity().findViewById(R.id.rent_list);
if (listView != null) {
listView.setAdapter(mCardArrayAdapter);
}
}
Any idea what's missing in this code so any pressed card become highlighted ?
If you are using the CardViewNative, you have to customize this style:
<style name="card.native.main_layout_foreground">
<item name="android:foreground">?android:selectableItemBackground</item>
<item name="android:background">#color/card_native_background</item>
<item name="android:layout_marginTop">#dimen/card_main_layout_native_view_margin_top</item>
<item name="android:layout_marginBottom">#dimen/card_main_layout_native_view_margin_bottom</item>
<item name="android:layout_marginLeft">#dimen/card_main_layout_native_view_margin_left</item>
<item name="android:layout_marginRight">#dimen/card_main_layout_native_view_margin_right</item>
</style>
Otherwise, if you are using the old CardView you can read this:
https://github.com/gabrielemariotti/cardslib/blob/master/doc/CARD.md#customize-card-background

using a custom color for button background while using selectableItemBackground attribute

I am trying to use
android:background="?android:attr/selectableItemBackground"
to get my button to do appropriate effects for each android version like rippling, etc.
But this produces a button with a grey color when I need a different color.
How can I override this default color ?
If you read the source code of Button.java then you will see that it is a subclass of TextView.java. I have made a simple workaround for the problem in question.
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:background="#1f5050">
<TextView android:layout_width="some_dp"
android:layout_height="some_dp"
android:id="#+id/button"
android:background="?android:selectableItemBackground" />
</LinearLayout>
In code:
button.setOnClickLisetener(new Onclicklistener() {
// do your stuff here
}
It would be much better if someone can extend the TextView class and make a custom Button with the feature in question.
Note: my minsdk is 14. also, the lollipop ripple effect works just fine
Just move your desired color in outer/parent level, e.g. "#color/Red" is button color:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/Red"
android:layout_weight="1">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:text="Hello"
android:textColor="#color/White"/>
</LinearLayout>
Using this method, you can customize ripple effect color. First, you have to create an xml file in your drawable resource directory. Create a ripple_effect.xml file and add following code. I use background colour as Red.
res/drawable/ripple_effect.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#af0c0e"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#af0c0e" />
</shape>
</item>
</ripple>
And set background to above drawable resource file. Final code of xml layout activity looks like this.
res/layout/ripple_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:paddingBottom="30dp"
app:cardBackgroundColor="#e7e7e7"
android:id="#+id/cardview"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:background="#drawable/ripple_effect">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
android:paddingBottom="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pending"
android:layout_weight="1"
android:layout_marginBottom="2dp"
android:textSize="25dp"
android:textColor="#d11010"
android:id="#+id/txtpending" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Assigned to:"
android:layout_marginLeft="20dp"
android:textColor="#ff000000"
android:id="#+id/txtassigned"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:layout_marginLeft="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Student Name"
android:id="#+id/txtstudentname"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Student Number"
android:id="#+id/txtstudentnumber"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Parent Name"
android:id="#+id/txtparentname"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Parent Number"
android:id="#+id/txtparentnumber"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Transfer Status"
android:id="#+id/txttransfer"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
Now,ripple effect is Red colour.
if you want to do it programmatically:
fun setSelectableBgWithColor(view: View, bgColor: Int? = null) {
val bgSelectable = getDrawableResCompat(view.context, android.R.attr.selectableItemBackground)
val bg = if (bgColor == null) bgSelectable else LayerDrawable(
arrayOf(ColorDrawable(color), bgSelectable)
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.background = bg
} else {
view.setBackgroundDrawable(bg)
}
}
fun getDrawableResCompat(context: Context, #AttrRes id: Int): Drawable? {
return TypedValue()
.also { context.theme.resolveAttribute(id, it, true) }
.let {
val resId = if (it.resourceId != 0) it.resourceId else it.data
ContextCompat.getDrawable(context, resId)
}
}
Edit: this is now possible using AppCompat and backgroundTint
android:backgroundTint="#color/yourColor"
Previous solution:
I had the same problem and ended up doing this programmatically:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ColorStateList colors = new ColorStateList(new int[][]{
new int[]{android.R.attr.state_enabled},
}, new int[]{pressed});
GradientDrawable item = new GradientDrawable();
item.setCornerRadius(radius);
item.setColor(normal);
RippleDrawable ripple = new RippleDrawable(colors, item, null);
button.setBackgroundDrawable(ripple);
} else {
StateListDrawable stateListDrawable = new StateListDrawable();
GradientDrawable item;
item = new GradientDrawable();
item.setCornerRadius(radius);
item.setColor(pressed);
stateListDrawable.addState(new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed}, item);
item = new GradientDrawable();
item.setCornerRadius(radius);
item.setColor(normal);
stateListDrawable.addState(new int[]{android.R.attr.state_enabled}, item);
button.setBackgroundDrawable(stateListDrawable);
}
Instead of using ?android:attr/selectableItemBackground you can create a xml in drawable in folder with following content.
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true">
<item
android:state_pressed="true"
android:drawable="#color/orange"/>
<item
android:state_enabled="false"
android:drawable="#color/default"/>
<item
android:drawable="#color/default"/>
</selector>
Updated: so you save this files as btn_drawable.xml in drawable folder.
Simply replace ?android:attr/selectableItemBackground with #drawable/btn_drawable.xml

Categories

Resources