I want to draw a simple line on top of some text in a TextView. I have looked at various examples which seem to override the onDraw() function but my understanding is that onDraw() is called when something is drawn.
I would like a vertical line in my TextView and at this moment in time I dont really care where it is, once I have the line I am sure I will be able to manipulate it to the position I would like.
I have a TextViewWithLines class extending TextView where the code will go:
public class TextViewWithLines extends TextView {
public TextViewWithLines(Context context){
super(context);
}
public TextViewWithLines(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TextViewWithLines(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
and I also have a fragment where I would like the drawing of the line to be done when I create the view.
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.fragment_hello_moon, parent, false);
t1 = (TextViewWithLines)v.findViewById(R.id.display1);
.................
}
Any help would be appreciated
As you describe, you simply need to do your drawing in onDraw().
Here is a (working) example of someone that wants all text in the Textview underlined;
How can I have a row separating line in TextView
One possible solution (just a simple XML layout):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/small_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textStyle="bold"
android:textSize="#dimen/define_your_size"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
/>
<LinearLayout
android:id="#+id/text_separator"
android:layout_width="match_parent"
android:layout_height="1dp"
android:orientation="vertical"
android:background="#color/define_your_color"
android:layout_alignParentTop="true"/>
</RelativeLayout>
If you want to draw a shape around a TextView (like a rectangle), you can define a drawable background and set the colors you want:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<shape>
<stroke android:color="#FFCC00" android:width="3dp"></stroke>
<corners android:radius="5dp"/>
<solid android:color="#FAFFA8"/>
</shape>
</item>
<item android:state_enabled="false">
<shape>
<stroke android:color="#FFFFFF" android:width="2dp"></stroke>
<corners android:radius="5dp"/>
<solid android:color="#00FFFFFF"/>
</shape>
</item>
<item>
<shape>
<stroke android:color="#DADADA" android:width="2dp"></stroke>
<corners android:radius="5dp"/>
<solid android:color="#FFFFFF"/>
</shape>
</item>
</selector>
Related
I'm trying to set "2 backgrounds" to a button, the first one is an xml file to make the button corners rounded and the second one is the png image that I want.
I tried to use android:background for my xml file and android:drawableTop for my image it's working but my image is not scalled in the button.
I know that we can use an imagebutton with android:scaleType="centerInside" to scale the picture but in my case I want to do it for a button because I need to put text in it ...
Can you help me with that ?
my xml file (for the rounded shape) :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#FF008AB8"/>
<stroke android:color="#0299D0"/>
<corners android:radius="15dp"/>
</shape>
</item>
android:radius = "150dp"</selector>
Thanks
LooKuM
You can use a layerlist in xml drawable such that you set both the xml background and image as you exactly need then you set the background just once.
Here is an example
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<corners android:radius="#dimen/quarter_margin" />
<stroke
android:width="1dp"
android:color="#color/ash_gray" />
<solid android:color="#color/white" />
</shape>
</item>
<item android:drawable="#drawable/blue_back">
</item>
</layer-list>
Another Solution:
To be able to use just one layout and control the image, You can make you own custom control, here is an example
public class RecordButton extends LinearLayout {
#BindView(R.id.record_switch)
SwitchCompat recordSwitch;
#BindView(R.id.record_toggle_button)
ToggleButton recordButton;
private boolean checkable = true;
public RecordButton(Context context) {
super(context);
init(context, null);
}
public RecordButton(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public RecordButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(#NonNull Context context, #Nullable AttributeSet attrs) {
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.record_button, this);
ButterKnife.bind(this);
setGravity(Gravity.CENTER_HORIZONTAL);
applyAttr(attrs);
setChecked(false);
}
private void applyAttr(#Nullable AttributeSet attrs) {
if (attrs != null) {
TypedArray a = getContext().getTheme().obtainStyledAttributes(attrs,
R.styleable.RecordButton, 0, 0);
// Set Image
int drawableResource = a.getResourceId(R.styleable.RecordButton_drawable, -1);
if (drawableResource > -1) {
int color = a.getColor(R.styleable.RecordButton_tint, -1);
if (color > -1) {
Drawable drawable = ContextCompat.getDrawable(getContext(), drawableResource);
Drawable wrapDrawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(wrapDrawable, Color.RED);
recordSwitch.setBackground(wrapDrawable);
} else {
recordSwitch.setBackgroundResource(drawableResource);
}
}
// Set Orientation
boolean isVertical = a.getBoolean(R.styleable.RecordButton_isVertical, false);
if (isVertical) {
setOrientation(VERTICAL);
}
a.recycle();
}
}
}
Here I inflated a layout and added to this class which inherits from LinearLayout
Here is the layout inflated
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.widget.SwitchCompat
android:id="#+id/record_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:thumb="#android:color/transparent" />
<ToggleButton
android:id="#+id/record_toggle_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:clickable="false"
android:minHeight="0dp"
android:minWidth="0dp"
android:padding="#dimen/standard_margin"
android:textAllCaps="false"
android:textColor="#color/colorPrimary" />
</merge>
Now you main question comes, how can I change the image. In Java class you will find a method called applyAttr this method takes takes the custom attributes you added to your custom control
Here is an attr sample
this code to attrs.xml file
<declare-styleable name="RecordButton">
<attr name="drawable" format="reference" />
</declare-styleable>
I don't know if this works(and I can't add a comment lol) but try to set the Image in the rounded Corners XML file.
I was wondering if there is a way to animate the background from a relativelayout , so that the color changes from e.g blue to yellow, from left to right in about 1 second. (This animation should be triggered onclick).
Appreciate any help,
ty
I think that you can use AnimationDrawable, the most basic way it's to have three color : blue, a gradient blue-yellow and yellow :
In res/drawable create a gradient.xml file (left to right):
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="0"
android:endColor="#FFFF00"
android:startColor="#0000FF" />
</shape>
Then in the same folder create a animalion-list.xml file :
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#0000FF" android:duration="333"/>
<item android:drawable="#drawable/gradient" android:duration="333"/>
<item android:drawable="#FFFF00" android:duration="333"/>
</animation-list>
Apply the animation-list as background to your relative layout :
<RelativeLayout:
android:...
android:...
android:drawable="#drawable/animation-list"
android:... >
...
</RelativeLayout>
In your code :
RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relative_layout_id);
AnimationDrawable animationDrawable = (AnimationDrawable) relativeLayout.getBackground();
mybutton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
animationDrawable.start();
}
});
I'm not sur that this code give you that your exactly expected but with some imagination, you should get that you want.
Hope this helps.
Drawable gradient_2
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#color/deep_purple_500"
android:endColor="#color/blue_700"
android:angle="0"/>
</shape>
and usage inside xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/gradient_2"
android:orientation="vertical">
</LinearLayout>
You can change agle of colorfull 0 , 45 , 90 , 180
android:angle="0"
You can also add centerColor
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="0"
android:centerColor="#D8EDFD"
android:endColor="#D8EDFD "
android:startColor="#F6F9FF " />
</shape>
I have listview (android.support.v7.widget.RecyclerView ) in my HomeLayout.
Code in HomeLayout
<LinearLayout
p1:orientation="horizontal"
p1:minWidth="25px"
p1:clickable="true"
p1:minHeight="25px"
p1:layout_width="wrap_content"
p1:layout_height="45dp"
p1:id="#+id/linearLayout2"
p1:layout_alignParentTop="true"
p1:layout_alignParentLeft="true"
p1:layout_marginLeft="70dp"
p1:layout_marginTop="15dp"
p1:layout_marginRight="310dp">
<android.support.v7.widget.RecyclerView
p1:id="#+id/categoriesListView"
p1:duplicateParentState="true"
p1:state_checked="true"
p1:focusable="true"
p1:focusableInTouchMode="true"
p1:clickable="true"
p1:scrollbars="horizontal"
p1:state_activated="true"
p1:layout_width="match_parent"
p1:layout_height="45dp" />
</LinearLayout>
List view have custom adapter. Adapter code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:p1="http://schemas.android.com/apk/res/android"
p1:orientation="horizontal"
p1:focusable="true"
p1:focusableInTouchMode="true"
p1:clickable="true"
p1:minWidth="25px"
p1:minHeight="25px"
p1:layout_width="match_parent"
p1:layout_height="match_parent"
p1:id="#+id/linearLayout1">
<TextView
p1:text="Medium Text"
p1:background="#drawable/designforselected"
p1:textAppearance="?android:attr/textAppearanceMedium"
p1:layout_width="wrap_content"
p1:layout_height="45dp"
p1:id="#+id/txtCategoryName"
p1:textSize="20dp"
p1:focusable="true"
p1:focusableInTouchMode="true"
p1:clickable="true"
p1:textColor="#drawable/textcolorarticle"
p1:gravity="center"
p1:fontFamily="Myriad"
p1:paddingRight="20dp"
p1:paddingLeft="20dp"
p1:paddingTop="10dp"
p1:paddingBottom="10dp"
p1:layout_marginLeft="5dp" />
</LinearLayout>
Textview have custom design for press p1:background="#drawable/designforselected" Code for designforselected is
<?xml version="1.0" encoding="UTF-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<shape android:shape="rectangle"/>
<solid android:color="#333333" />
</item>
<item android:state_pressed="true" >
<shape android:shape="rectangle"/>
<solid android:color="#333333" />
</item>
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#b3b3b3"
android:endColor="#e6e6e6"
android:angle="90"/>
<corners
android:topLeftRadius="5dp" android:topRightRadius="5dp" android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp" >
</corners>
</shape>
</item>
</selector>
State_pressed is work but state_selected no work. Why ? Ty
I wish the solution to XML file
You need to implement the listView onClick like this:
listContent.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String item = ...;
Toast.makeText(getBaseContext(), item, Toast.LENGTH_LONG).show();
}
});
I had similar issue not long ago with state_selected. Try state_checked or state_activated instead.
In your adapter write this:
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int i) {
final GridItem nature = mItems.get(i);
viewHolder.tvspecies.setText(nature.getName());
viewHolder.imgThumbnail.setImageResource(nature.getThumbnail());
viewHolder.imgThumbnail.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.i("CLick",nature.toString());
}
});
}
This is a way that works to me. Of course you need use your ids
I was going through this tutorial and had the idea of making it so when you press a button, one of the cards borders changes color.
I looked at this solution, but nothing happens.
Here is what I have done:
I have an xml in drawable for the shape (feed_item.xml):
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Bottom 2dp Shadow -->
<item>
<shape android:shape="rectangle">
<solid android:color="#d8d8d8" />
<corners android:radius="7dp" />
</shape>
</item>
<!-- White Top color -->
<item android:bottom="3px" android:id="#+id/feedsquare">
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- view background color -->
<solid
android:color="#color/white" >
</solid>
<!-- view border color and width (I WANT TO CHANGE THIS) -->
<stroke
android:width="1dp"
android:color="#color/white" >
</stroke>
<!-- If you want to add some padding -->
<padding
android:left="4dp"
android:top="4dp"
android:right="4dp"
android:bottom="4dp" >
</padding>
</shape>
</item>
</layer-list>
Then I have a layout that is basically how each card/list item looks (list_row.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:background="#drawable/feed_item"
android:id="#+id/card"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
android:padding="2dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:id="#+id/title"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_width="wrap_content"
android:text="MMMMMMMMMM"
android:textSize="#dimen/name3"
android:textColor="#color/black" />
<!--android:scaleType="fitXY"-->
<ImageView android:id="#+id/list_image"
android:layout_height="180dp"
android:layout_margin="2dp"
android:layout_weight="0.04"
android:layout_width="match_parent"
android:scaleType="centerInside"
android:adjustViewBounds="true"
android:src="#mipmap/navigation_refresh"/>
<TextView android:id="#+id/description"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_width="wrap_content"
android:text="MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM"
android:textSize="#dimen/description3"
android:textColor="#color/black" />
</LinearLayout>
Now, I have a fragment with a listview. The fragment does exactly what the tutorial does (show 8 cards). I've added a button to the fragment that I want to change a specific cards border color (in the fragments onactivitycreated):
newpost = (Button) getActivity().findViewById(R.id.reply);
newpost.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LayerDrawable layers = (LayerDrawable) getActivity().getResources().getDrawable(R.drawable.feed_item);
GradientDrawable shape = (GradientDrawable) (layers.findDrawableByLayerId(R.id.feedsquare));
shape.setStroke(1 ,R.color.green);
}
});
Nothing happens when I press the button. Any ideas as to what I can do?
To show selected item (row) in listview :
create a variable in adapter class :
private int selectedPosition = 0;
Create method in side adapter :
public void setSelectedItem(int position) {
this.selectedPosition = position;
notifyDataSetChanged();
}
Add check in getView methode
if (position == selectedPosition)
{
convertView.setBackground(context.getResources().getDrawable(R.drawable.selector_rect_black_trans_bg));
}
else convertView.setBackgroundColor(context.getResources().getColor(android.R.color.transparent));
selector_rect_black_trans_bg.xml :
<solid android:color="#color/gray1" />
<stroke
android:width="2dp"
android:color="#color/gray6" />
<corners
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="0dp"
android:topRightRadius="0dp" />
In Activity, only you need to pass position in adapter to show highlighted.
its tested code and it will work.
I am messing around with creating my own dialog class, but I've run into an interesting issue. I use a layer-list drawable for the dialog's close button, but for some reason, the shadow layer disappears after the first time I show the dialog. You can see in the image below:
I really have absolutely no idea what could be causing this. I've tried debugging, but I wasn't able to find any leads. Does anyone have any ideas? My code is below.
TwoColorDialog.java
public class TwoColorDialog extends DialogFragment {
private static final String TAG = "TwoColorDialog";
private ViewGroup _root;
private TextView _textTitle;
private ImageView _buttonClose;
private Button _button1;
private Button _button2;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Dialog dialog = new Dialog(getActivity());
_root = (ViewGroup) getActivity().getLayoutInflater().inflate(R.layout.two_color_dialog, null);
_textTitle = (TextView) _root.findViewById(R.id.dialog_title);
_buttonClose = (ImageView) _root.findViewById(R.id.dialog_close_button);
_button1 = (Button) _root.findViewById(R.id.dialog_button1);
_button2 = (Button) _root.findViewById(R.id.dialog_button2);
dialog.requestWindowFeature(STYLE_NO_TITLE);
View decorView = dialog.getWindow().getDecorView();
decorView.setBackgroundResource(getResources().getColor(android.R.color.transparent));
dialog.setContentView(_root);
_buttonClose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog.cancel();
}
});
_button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d(TAG, "Button 1 pressed");
}
});
_button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d(TAG, "Button 2 pressed");
}
});
return dialog;
}
}
two_color_dialog.xml
<?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"
android:orientation="vertical">
<LinearLayout android:id="#+id/dialog_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/dialog_background">
<LinearLayout android:id="#+id/dialog_title_spacing"
android:layout_width="match_parent"
android:layout_height="24dp"
android:orientation="horizontal" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<Button android:id="#+id/dialog_button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="6dp"
android:background="#drawable/button"
android:text="Button1" />
<Button android:id="#+id/dialog_button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="6dp"
android:background="#drawable/button"
android:text="Button2" />
</LinearLayout>
</LinearLayout>
<TextView android:id="#+id/dialog_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|top"
android:layout_marginTop="6dp"
android:background="#drawable/dialog_title_box"
android:textAppearance="#android:style/TextAppearance.Large"
android:text="TITLE" />
<ImageView android:id="#+id/dialog_close_button"
android:layout_width="42dp"
android:layout_height="44dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_gravity="top|right"
android:src="#drawable/dialog_close_button"/>
</FrameLayout>
dialog_title_box.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#88888888" />
<corners android:radius="1dp" />
<padding
android:left="1dp"
android:top="0dp"
android:right="1dp"
android:bottom="3dp" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#color/white" />
<corners android:radius="1dp" />
<padding
android:left="15dp"
android:top="5dp"
android:right="15dp"
android:bottom="5dp" />
</shape>
</item>
</layer-list>
dialog_close_button.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="#88888888" />
<padding
android:left="1dp"
android:top="0dp"
android:right="1dp"
android:bottom="4dp" />
</shape>
</item>
<item>
<shape android:shape="oval">
<solid android:color="#color/white" />
</shape>
</item>
<item android:drawable="#drawable/ic_close" />
</layer-list>
Well, I've found the issue. The problem only shows up when you use the "padding" tag. I have no idea why, maybe it is a bug. I was able to work around it by changing my dialog_close_button.xml accordingly:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="#88888888" />
</shape>
</item>
<item
android:left="1dp"
android:right="1dp"
android:bottom="4dp">
<shape android:shape="oval">
<solid android:color="#color/white" />
</shape>
</item>
<item
android:drawable="#drawable/ic_close"
android:left="1dp"
android:right="1dp"
android:bottom="4dp" />
</layer-list>