I'm making a to-do app and I'm using a RecyclerView to create a multiple grid layout like this:
I'm using a background layout to round the corners:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="6dp" />
<corners android:radius="20dp"/>
</shape>
My problem is that whenever I change the color dynamically in the adapter like this:
public void onBindViewHolder( ViewHolder holder, int position) {
holder.timee.setBackgroundColor(task.get(position).getColor());
holder.timee.setTextColor(Color.WHITE);
holder.grid.setBackgroundColor(Color.WHITE);
holder.namee.setTextColor(task.get(position).getColor());
}
The background color seems to ignore the boundaries I've set with the background layout and I get this result:
What is the best way to make it have both rounded corners and a different color for every item in the RecycerView?
The background "layout" you are using is in fact not a layout at all; It is a drawable resource. This means that though the visible borders are rounded, the view itself still has its original shape.
When you set a background color programmatically, it replaces the previous drawable that had rounded corners and fills the entire rectangular view. In order to have both rounded corners, and a solid color fill within those bounds, you will need to modify your drawable itself. The <solid> tag should suit this purpose.
To support multiple colors, you can either have separate drawable resources for each of them (useful if you have just a couple of them), or you can use different tints on a base drawable. Other methods can be found at this question.
This doesn't directly answer your question, but it offers an alternative that I find much easier to manage.
When I need views with rounded corners, I tend to use a CardView and I just remove the elevation. I can then modify the layout like any other programmatically:
<android.support.v7.widget.CardView
android:layout_width="50dp"
android:layout_height="50dp"
card_view:cardBackgroundColor="#5500FF00"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="0dp" />
So you just use the CardView in your list item view that's inflated, and then in your code you simply do this:
public void onBindViewHolder( ViewHolder holder, int position) {
...
holder.cardView.setCardBackgroundColor(task.get(position).getColor());
...
}
Related
Is it possible to add a bitmap as border of an ImageView in android dynamically in Java?
I have already tried the following:
Image view in XML and border as shape the result is wrong I want to add bitmap in border.
You have got multiple options:
Place an other View with the border (also imageview) above your Imageview. Thay might be the simples solution. Just add an other view to your xml and make sure they are overlapping. (Use for example a Relative or FrameLayout as container)
Use a Layer List and draw a shape above a Bitmap and add that to your ImageView
Write a custom ImageView and use the Canvas to draw the Border in the overwritten onDraw method. E.g. canvas.drawRect(...) its pretty straightforward.
The simple way:
A drawable for ImageView's attr that android:foreground
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:width="1px" android:color="#ff0000" />
<solid android:color="#android:color/transparent"/>
</shape>
Then XML,
<ImageView
android:id="#+id/unreserved_head_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:foreground="#drawable/shape_border"
/>
The simplest solution I found recently.
Try to use material theme in your app. Use "Theme.MaterialComponents.Light"
Then use image view inside and material card view.
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="#color/white"
app:cardCornerRadius="8dp"
app:cardElevation="0dp"
app:strokeColor="#color/colorPrimary"
app:strokeWidth="1dp">
<ImageView/>//define you image view hear
</com.google.android.material.card.MaterialCardView>
With property stokeColor and strokeWidth you can have border on an image view and make it dynamic.
you can use 9 patch in andorid studio to make an image a border!
i was finding a solution but i did not find any so i skipped that part
then i go to the google images of firebase assets and i accidentaly discovered that they use 9patch
heres the link: https://developer.android.com/studio/write/draw9patch
you just need to drag where the edges are
its just like boder edge in unity
How can i create a layout which has circles and inside the circles are hidden numbers once clicked you view the number?. I would like this kind of layout where i have numbers displayed for seconds and hidden by such shapes but i dont know how to achieve this. I am still new in the Android Studio and any help at this moment will be helpful.
This is what i would want it to look like. I want to display on 5 circle/oval buttons with numbers hidden inside and after clicking them that is when you see the numbers
circle.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
<gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF"
android:angle="270"/>
</shape>
using a view with bacackground as circle.xml create a circle
<View android:layout_width="50dp"
android:layout_height="50dp"
android:background="#drawable/circle"/>
Then onclick hide this layout.show a textview at the position of this layout.
fairly new to Android development and I've got a question I've Google'd the crap out of and can't find a solid answer on.
I simply want to know how to determine when the position in a ListView changes. Specifically, I've got a ListView whose TextView text changes color when I click on it. The problem is, when I click on a different position in the ListView, the color of the text of the position I was just on stays what it was changed to.
Basically, is there a way to listen for a position change in a ListView, and then execute code when that position changes?
Thanks a lot!
If you only want one item to be selected at a time make sure you set the choice mode to single when you're setting up your ListView.
myListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE)
You'll need to set an onItemClickListener.
myListView..setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long rowId) {
// Your Code Here
}
});
When you set up your ArrayAdapter you can use one of the default Android item layouts such as simple_list_item_activated_1, which highlights the background of the selected item.
myArrayAdapter = new ArrayAdapter<String>(getContext(),
android.R.layout.simple_list_item_activated_1, myArrayList);
If you want your own custom behavior such as changing the text color rather than the background, then simply replace the item layout with one of your own. Have a look at the default Android item layouts to see how they write them. For example, below is the default Android item layout android.R.layout.simple_list_item_activated_1, where you can see they've used a selector called activatedBackgroundIndicator to define the background color.
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/activatedBackgroundIndicator"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
/>
<Additional>
In your case, to get the text color to change instead of the background, you will want to use a selector for your text color. Make a color folder in your res directory. Create a selector in it:
my_color_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:color="#color/my_red_color />
<item android:drawable="#color/my_blue_color" /> <!-- color when not selected -->
</selector>
Then in your custom item layout set the color of your text to my_color_selector
I have a TextView with a drawable as background. Using a StateListDrawable object I'm trying to set the background colour programmatically, but I'm running into unexpected behaviour: I set the colour in one object, and it changes in another. This should be impossible.
The relevant code:
GradientDrawable notPressed = (GradientDrawable) getResources().getDrawable(R.drawable.rectangle);
GradientDrawable isPressed = (GradientDrawable) getResources().getDrawable(R.drawable.rectangle);
isPressed.setColor(util.getColour(api, this));
StateListDrawable bg = new StateListDrawable();
// bg.addState(new int[] { android.R.attr.state_pressed }, isPressed);
bg.addState(StateSet.WILD_CARD, notPressed);
textView.setBackgroundDrawable(bg);
The drawable:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:width="1dp" android:color="#color/divider" />
<solid android:color="#color/background_button" />
</shape>
util.getColour returns a colour resource based on the value of api.
The strange thing is that in the above code the colour of the isPressed drawable is set, but after that this drawable is not used. Instead only the notPressed drawable is added to the background of the textView.
But the background colour of the textView becomes the colour of the isPressed drawable instead! This should be impossible, as they should be two different objects, even if they are created from the same drawable resource.
I think that when you get a resource you get the same reference to it. So notPressed and isPressed are the same object. I believe there's a clone operation somewhere...
Edit:
Yep, you have to call mutate() on the drawable before you modify it. See Adding a color filter to a Drawable changes all Buttons using the same Drawable.
Android uses the same object for drawable resources unless you specify that you need a new copy of it.
you can use this code to solve this issue:
Drawable isPressed = notPressed.getConstantState().newDrawable();
I need to have a dialog (it's a game dialog) where buttons are at the lower corners of the dialog. Not inside the dialog but rather on the very corners (i.e. part of the button will reside over the dialog and the part will be outside of it).
First, as far as I know you can't move layout children outside their parent.
I've never tried exactly what you're going for, but I think it can be done. The trick would be to go with an activity with a dialog theme (you can find examples of these on the developer site or the API demos). Make sure your layout's root node has width and height set to wrap_content. Your root layout should be a RelativeLayout and have NO background (android:background="#0000").
Next, add another layout to your root node (FrameLayout would probably work) with a custom drawable for a background (or use the one that the default dialog uses from the framework) and width and height set to fill_parent or match_parent. Set android:padding to some dip value which pulls the background in from the edge of the dialog.
The only thing left to do would be to add your other layout elements to the root node. The FrameLayout will be drawn beneath everything else, and the padding will create the illusion of borders which do not encompass your UI.
Update
Yikes, just tried the above with good and bad results. First, you'll definitely want to look at the "Custom Dialog" example from the API demo, which makes use of:
CustomDialogActivity.java
layout/custom_dialog_activity.xml
xml/styles.xml
drawable/filled_box
Create an activity which uses the above xml layout file, and set the style for the activity to Theme.CustomDialog that you defined in xml/styles.xml. This will get you a red background for your activity. You can then edit the filled_box shape file to just have one background attribute set to invisible ("#0000"). The result should be an dialog-shaped activity with no background.
Next I tried to hack a background using my thoughts from above. The idea should be that there's a phony background drawn behind the other UI elements which does not encompass them, so it could be "shrunk" using layout_margin and not affect them. The problem here is that the phony background needs to have width and height set to relative to the other UI elements, so it sort of HAS to encompass them, so it can properly measure its own width and height relative to them.
So I think the solution could be to do most of what I've said above, except don't try the phony background thing. Just use a 9-patch drawable for your root layout background, and shrink the edges of your background to be drawn farther in than your content. You'd still use the custom theme stuff from above with an invisible window theme.
Here is a sample layout which i tried:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<FrameLayout
android:orientation="vertical"
android:id="#+id/ll1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:drawable/dialog_frame">
</FrameLayout>
<Button android:layout_width="wrap_content"
android:id="#+id/button1"
android:layout_height="wrap_content"
android:layout_marginTop="35dp"
android:layout_centerHorizontal="true"
android:text="Button"></Button>
</RelativeLayout>
here is the screenshot:
hope u get the hint , goodluck