Unable to set Background in Imagebutton - android

Here i have a ImageButton:
<com.defcomdevs.invento16.SquareImageView
android:id="#+id/picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal|top"
android:background="#drawable/custom_button"
android:layout_margin="1dp"
android:scaleType="fitCenter" />
SquareImageView is a class that extends the Imagebutton to basically set the width and height automatically according to the Screen size.
custom_button.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false">
<shape android:shape="rectangle">
<stroke android:width="5dp" android:color="#885599"/>
</shape>
</item>
<item android:state_pressed="true">
<shape android:shape="rectangle">
<stroke android:width="8dp" android:color="#802196f3"/>
<gradient android:startColor="#802196f3" android:endColor="#802196f3"/>
</shape>
</item>
My Problem is that when i set the background as custom_button the image that i set programmatically overlaps the entire area of the button.not showing the background.Otherwise the image perfectly sets inside the button.
Some thing like this:
As you can see this is the case with background=custom_button.
this is the case otherwise.
Now i don't want any of these.
What i want is that the custom_button is set as the background of the ImageButton and the src as that image as shown.How to da that??Please help.Thanks.
SquareImageView.class:
package com.defcomdevs.invento16;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Button;
import android.widget.ImageButton;
public class SquareImageView extends ImageButton {
public SquareImageView(Context context) {
super(context);
}
public SquareImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth()); //Snap to width
}
}

Related

Add Background property to Custom TextView component with only border at bottom

I am trying to add a drawable background to a CustomTextView on android. I tried using style attribute in styles.xml but I was unable to apply it.
Here is my implementation so far.
CustomTextView.java
public class CustomTextView extends android.support.v7.widget.AppCompatTextView {
public CustomTextView(Context context) {
super(context);
Typeface face = Typeface.createFromAsset(context.getAssets(), "font/Montserrat-Regular.ttf");
context.getDrawable(R.drawable.tv_bottom_line_only);
this.setTypeface(face);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
context.getDrawable(R.drawable.tv_bottom_line_only);
Typeface face = Typeface.createFromAsset(context.getAssets(), "font/Montserrat-Regular.ttf");
this.setTypeface(face);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
Typeface face = Typeface.createFromAsset(context.getAssets(), "font/Montserrat-Regular.ttf");
context.getDrawable(R.drawable.tv_bottom_line_only);
this.setTypeface(face);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
}
My drawable file:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="1dp"
android:left="-2dp"
android:right="-2dp"
android:top="-2dp">
<shape android:shape="rectangle">
<stroke
android:width="0.5dp"
android:color="#android:color/black" />
</shape>
</item>
Here, is my implementation in layout xml.
...
<com.project.utils.CustomTextView
android:id="#+id/profile_et_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:inputType="text"
android:padding="#dimen/_4sdp"
android:textColor="#color/black"
android:textSize="#dimen/_8sdp" />
Here is the snapshot of the issue. I want to remove the border appearing in top.
Thank you
To set the drawable as your background you should use :
setBackground(context.getDrawable(R.drawable.tv_bottom_line_only));
Now to have only a line at the bottom, you should remove the rectangle shape from your drawable.
MainActivity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Layout 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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:gravity="center">
<org.mayday.myapplication.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</LinearLayout>
tv_bottom_line_only xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="-8dp" android:left="-8dp" android:right="-8dp">
<shape>
<stroke android:width="0.5dp" android:color="#android:color/black" />
</shape>
</item>
</layer-list>
Result:

Custom button with text and image

I'm looking for do a button like this preview :
I tried to do this with a button but my problem is that to put the border and the image I use android: background and I can not put the image and the border at the same time :/
Another problem for which I did not know how is a border to the text (which is simply the text of the button).
I wonder if I'm going in the wrong direction. I saw that there were button images but I'm not sure it suits me. Would there be a way to put a layout to a button?
<Button
android:id="#+id/mainButton1"
style="#style/Widget.AppCompat.Button.ButtonBar.AlertDialog"
android:layout_width="150"
android:layout_height="150"
android:background="#drawable/ic_add_circle_green_500_48dp"
android:drawable="#drawable/mainButton" <-- or android:drawable="#drawable/image" how for put the both ? -->
android:text="Text"
/>
mainButton.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient android:startColor="#FFFFFF"
android:endColor="#00FF00"
android:angle="270" />
<corners android:radius="3dp" />
<stroke android:width="5px" android:color="#000000" />
</shape>
i have found many answers on Stackoverflow but the link to tutos was dead ...
You can create your custom View with desired background and ImageView,TextView inside. Then set ClickListener to it.
If you want background behind TextView you can use SpannableString or just create XML drawable and set it as TextView background.
Here what i've done:
Button class:
public class CustomButton extends LinearLayout {
public CustomButton(Context context) {
super(context);
inflateLayout(context);
}
public CustomButton(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
inflateLayout(context);
}
public CustomButton(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
inflateLayout(context);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomButton(Context context, #Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
inflateLayout(context);
}
private void inflateLayout(Context context) {
inflate(context, R.layout.custom_button, this);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
TextView textView = findViewById(R.id.textView);
makeSpannable(textView);
}
private void makeSpannable(TextView textView) {
Spannable spannable = new SpannableString(textView.getText());
spannable.setSpan(new BackgroundColorSpan(0xFFFF0021), 0, textView.getText().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannable);
invalidate();
}
}
layout for CustomButton:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="vertical"
android:background="#drawable/background"
android:padding="16dp">
<ImageView
android:id="#+id/imageView"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:src="#mipmap/ic_launcher" />
<TextView
android:id="#+id/textView"
android:gravity="center_horizontal"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_width="match_parent"
android:text="CLICK ME!"
android:textSize="16dp" />
</LinearLayout>
background for button:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF"/>
<stroke android:width="3dp" android:color="#00FFFF" />
<corners android:radius="10dp"/>
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>
What I've got:

How to fix background red color TextInputLayout when isEmpty in Android

I want setError when TextInputLayout isEmpty, I write this code but when show error message, set red background for TextInputLayout!
I do not want set background! I want just show the error message.
My code:
if (TextUtils.isEmpty(userName)) {
register_UserName_layout.setError("Insert Username");
}
XML code :
<android.support.design.widget.TextInputLayout
android:id="#+id/register_userUsernameTextLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/register_headerLayout"
android:layout_margin="10dp"
android:textColorHint="#c5c5c5">
<EditText
android:id="#+id/register_userUserNameText"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#drawable/selector_bg_edit"
android:hint="نام کاربری"
android:paddingBottom="2dp"
android:textColor="#color/colorAccent"
android:textCursorDrawable="#drawable/bg_input_cursor"
android:textSize="16sp" />
</android.support.design.widget.TextInputLayout>
How can I fix this? Thanks all <3
I have found a workaround to this problem. You just need to create a custom EditText and override the getBackground() method of it to return a new drawable. That way TextInputLayout won't be able to set color filter on the EditText's background, since you do not return EditText's background, but some another drawable. See below:
#Override
public Drawable getBackground() {
return ContextCompat.getDrawable(getContext(), R.drawable.some_drawable);
}
and use the custom EditText inside TextInputLayout:
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CustomEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/custom_edit_text_bg" />
</android.support.design.widget.TextInputLayout>
in my case I added line
<solid android:color="#color/transparent"/>
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke android:color="#color/lightGray" android:width="1dp"/>
<solid android:color="#color/transparent"/>
<padding android:top="7dp" android:bottom="7dp" android:left="7dp" android:right="7dp"/>
<corners android:radius="2dp"/>
</shape>
this results in red border only not entire background
You can subclass TextInputLayout and use that:
package com.mypackage;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputLayout;
import android.util.AttributeSet;
public class CustomTextInputLayout extends TextInputLayout {
public CustomTextInputLayout(Context context) {
super(context);
}
public CustomTextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void drawableStateChanged() {
super.drawableStateChanged();
clearEditTextColorfilter();
}
#Override
public void setError(#Nullable CharSequence error) {
super.setError(error);
clearEditTextColorfilter();
}
private void clearEditTextColorfilter() {
EditText editText = getEditText();
if (editText != null) {
Drawable background = editText.getBackground();
if (background != null) {
background.clearColorFilter();
}
}
}
}
in your layout:
<com.mypackage.CustomTextInputLayout
android:id="#+id/register_userUsernameTextLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/register_headerLayout"
android:layout_margin="10dp"
android:textColorHint="#c5c5c5">
<EditText
android:id="#+id/register_userUserNameText"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#drawable/selector_bg_edit"
android:hint="نام کاربری"
android:paddingBottom="2dp"
android:textColor="#color/colorAccent"
android:textCursorDrawable="#drawable/bg_input_cursor"
android:textSize="16sp" />
</android.support.design.widget.TextInputLayout>
Bottom line with this issue is check if your EditText has a background color set. If so, remove it and put a background color on your text Input Layout widget instead. This will fix the issue of the big red box. At least it did for me.
Subclass EditText and apply the follow methods:
Override getBackground and create a Drawable with input background
#Override
public Drawable getBackground() {
return ContextCompat.getDrawable(getContext(), R.drawable.input_background);
}
your Drawable input_brackground can be like:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#color/inputBackgroundColor">
</solid>
</shape>
And apply EditText subclassed setBackground after TextInputLayout set error like:
private void showTheError(String error){
textInputLayout.setError(error);
editTextSubclassed.setBackgroundColor(getResources().getColor(R.color.inputBackgroundColor));
}
Similar to Shahin Mursalov's answer, I call method init() in the costructor to store the background drawable when the view is created. Also I've overriden method setBackgroundResource() to store the background as well, and return it from getBackground():
public class CustomEditText extends EditText{
private Drawable backgroundDrawable;
public EditTextContext context) {
super(context);
this.context = context;
}
public EditTextContext context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
init(attrs);
}
public EditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
init(attrs);
}
public void init(AttributeSet attrs){
TypedArray attributes = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.background});
this.backgroundDrawable = attributes.getDrawable(0);
attributes.recycle();
}
#Override
public void setBackgroundResource(#DrawableRes int resId) {
this.backgroundDrawable = ContextCompat.getDrawable(context, resId);
super.setBackgroundResource(resId);
}
#Override
public Drawable getBackground() {
if (backgroundDrawable != null){
return backgroundDrawable;
} else {
return super.getBackground();
}
}
}
This way I can specify a different background in my layout and change it programatically.
first your EditText background selector_bg_edit should be like that
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/code_view_item"
android:state_focused="true"/>
<item android:drawable="#drawable/sign_in_fields"
android:state_focused="false"/>
<item android:drawable="#drawable/sign_in_fields"
android:state_active="false"/>
</selector>
And the most important thing is to put in the drawable to be transparent color like this
code_view_item.xml
<stroke android:width="1dp" android:color="#15A859" />
<solid android:color="#00FFFFFF" />
<corners android:radius="12dp"/>
What worked for me is just putting this below lines in my custom edit text class :
override fun getBackground(): Drawable {
return this.context.getDrawable(R.drawable.myDrawableResource)
}
My solution:
yourEdit.background.clearColorFilter()
if (TextUtils.isEmpty(userName)) {
register_UserName_layout.setError("Insert Username");
txtInpit.setColorFilter(R.color.white);
}

Scrollbar color in RecyclerView

How can I change the color of my scrollbar in a recyclerView?
I have the scrollbar but I want to change its color.
My recyclerView is like this:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recyclerView"
android:layout_below="#id/my_toolbar"
android:layout_above="#+id/progressBar"
android:scrollbars="vertical"
/>
You can do this by including following line of code in your Recyclerview
android:scrollbarThumbVertical="#drawable/yoursdrawablefile
The drawable file in my case is:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:startColor="#000" android:endColor="#000"
android:angle="45"/>
<corners android:radius="6dp" />
</shape>
In case you want to further style your scrollbars, create two drawable resource file in your drawable folder as 1. scrollbar_track and 2. scrollbar_thumb
scrollbar_track.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:angle="0"
android:endColor="#9BA3C5"
android:startColor="#8388A4" />
<corners android:radius="6dp" />
</shape>
scrollbar_thumb.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:angle="0"
android:endColor="#b20111"
android:startColor="#cf1d2d" />
<corners android:radius="6dp" />
</shape>
Now, create a style named scrollbar_style in your styles.xml file as:
<style name="scrollbar_style">
<item name="android:scrollbarAlwaysDrawVerticalTrack">true</item>
<item name="android:scrollbarStyle">outsideOverlay</item>
<item name="android:scrollbars">vertical</item>
<item name="android:fadeScrollbars">true</item>
<item name="android:scrollbarThumbVertical">#drawable/scrollbar_thumb</item>
<item name="android:scrollbarTrackVertical">#drawable/scrollbar_track</item>
<item name="android:scrollbarSize">8dp</item>
<item name="android:scrollbarFadeDuration">800</item>
<item name="android:scrollbarDefaultDelayBeforeFade">500</item>
</style>
Finally, to apply this style to the scrollbar in your recyclerview, add
style="#style/scrollbar_style"
to your recyclerview.
In your case:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recyclerView"
style="#style/scrollbar_style"
android:layout_below="#id/my_toolbar"
android:layout_above="#+id/progressBar"
android:scrollbars="vertical"
/>
If you need to change the color in runtime, this is the way.
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
/**
* Created on 22.3.2016.
*
* #author Bojan Kseneman
* #description A recycler view that will draw the scroll bar with a different color
*/
public class CustomScrollBarRecyclerView extends RecyclerView {
private int scrollBarColor = Color.RED;
public CustomScrollBarRecyclerView(Context context) {
super(context);
}
public CustomScrollBarRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomScrollBarRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setScrollBarColor(#ColorInt int scrollBarColor) {
this.scrollBarColor = scrollBarColor;
}
/**
* Called by Android {#link android.view.View#onDrawScrollBars(Canvas)}
**/
protected void onDrawHorizontalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t, int r, int b) {
scrollBar.setColorFilter(scrollBarColor, PorterDuff.Mode.SRC_ATOP);
scrollBar.setBounds(l, t, r, b);
scrollBar.draw(canvas);
}
/**
* Called by Android {#link android.view.View#onDrawScrollBars(Canvas)}
**/
protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t, int r, int b) {
scrollBar.setColorFilter(scrollBarColor, PorterDuff.Mode.SRC_ATOP);
scrollBar.setBounds(l, t, r, b);
scrollBar.draw(canvas);
}
}
These methods are defined in View class, so the same princible should work of other views like ScrollView and ListView.

DrawerLayout Causing Slow Selector

I started implementing DrawerLayout in my application and I noticed that the selector for my button responds very slowly. When I change DrawerLayout to LinearLayout, the lag disappears. I'm not sure if this is caused by extra touch processing occurring in the DrawerLayout that causes this lag or something else. Is there anything I can do to reduce this lag?
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/my_button"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/button_background"
android:text="" />
</android.support.v4.widget.DrawerLayout>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<solid android:color="#000080"/>
</shape>
</item>
<item>
<shape>
<solid android:color="#0000ff"/>
</shape>
</item>
</selector>
DrawerLayout doesn't override shouldDelayChildPressedState() like LinearLayout does so it creates a delay. Had to create a layout class like this:
public class MyDrawerLayout extends DrawerLayout {
public MyDrawerLayout (Context context) {
super(context);
}
public MyDrawerLayout (Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyDrawerLayout (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean shouldDelayChildPressedState() {
// prevents touch delay
return false;
}
}
The only side effect I notice is the swipe gesture will select the view before bringing the drawer out.

Categories

Resources