Android simple widget to show image into ImageView - android

i'm created simple widget extends from ImageView, in this simle code i want to set image into ImageView from layout xml,i want change background imageview image and change image to set other image into ImageView, but my problem in first time dont show image
1) i'm create new attribute into attr.xml:
<declare-styleable name="CIconButton">
<attr name="button_icon" format="integer" />
<attr name="background_icon" format="reference" />
</declare-styleable>
2) use CIconButton class into layout:
<!-- xmlns:app="http://schemas.android.com/apk/res/com.sample.app.tpro" -->
<com.sample.widget.CIconButton
android:id="#+id/imgv_update_selected_phones"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
app:button_icon="#drawable/icon_add_action" />
3) CIconButton class
public class CIconButton extends ImageView implements OnClickListener {
private Drawable mSelectedBackground;
public CIconButton(Context context) {
super(context, null);
}
public CIconButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CIconButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CIconButton, defStyle, 0);
mSelectedBackground = a.getDrawable(R.styleable.CIconButton_button_icon);
setImageDrawable(mSelectedBackground);
a.recycle();
setOnClickListener(this);
}
#Override
public void onClick(View v) {
}
}
PROBLEM:
my custom widgets class dont show image set into layout xml, for example this class dont show icon_add_action from drawable

My problem resolved , i must be change second constructor as :
public CIconButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
to:
public CIconButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
this call last this class constrctor

Related

Unexpected namespace prefix app in child view of CustomLayout

I got the error when use attribute in child view of a CustomLayout (I have define a custom LayoutParams to allow child view use this attribute)
However, code's still RUNNING and display correct value (you can check my code below, when I run app it will display "Hello" in logcat)
Here is my code
style.xml
<declare-styleable name="CustomRelativeLayout_Layout">
<attr name="title" format="string" />
</declare-styleable>
CustomRelativeLayout class
public class CustomRelativeLayout extends RelativeLayout {
public CustomRelativeLayout(Context context) {
this(context, null);
}
public CustomRelativeLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new CustomLayoutParams(getContext(), attrs);
}
#Override
public void onViewAdded(View child) {
super.onViewAdded(child);
CustomLayoutParams layoutParams = (CustomLayoutParams) child.getLayoutParams();
Log.i("TAG", "title = " + layoutParams.title);
}
final class CustomLayoutParams extends RelativeLayout.LayoutParams {
String title;
CustomLayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
TypedArray ta =
c.obtainStyledAttributes(attrs, R.styleable.CustomRelativeLayout_Layout);
title = ta.getString(R.styleable.CustomRelativeLayout_Layout_title);
ta.recycle();
}
}
}
Of course, I can disable it by add tools:ignore="MissingPrefix" but I don't like this much. Any help or suggestion would be great appreciated.
Here is my demo https://github.com/PhanVanLinh/AndroidPassAttributeToChildVIew
After many try, I found a solution for my problem
Change title to layout_title will make the error gone
<declare-styleable name="CustomRelativeLayout_Layout">
<attr name="title" format="string" />
</declare-styleable>
The magic is layout_ because the error still happened if I use like
title_, title_dasdasdsad, lo_title, title_23232

set image dynamically to the custom imageview class android

I want to load the url into ImageView and that url is dynamic, so I created the custom Imageview class like this
public class CustomLocalCurrencyImageViewWhiteColor extends AppCompatImageView {
public CustomLocalCurrencyImageViewWhiteColor(Context context) {
super(context);
Glide.with(context).load(SessionManager.getCountryWiseDataObject(context).getCurrencyImageWhite()).into(this);
}
public CustomLocalCurrencyImageViewWhiteColor(Context context, AttributeSet attrs) {
super(context, attrs);
Glide.with(context).load(SessionManager.getCountryWiseDataObject(context).getCurrencyImageWhite()).into(this);
}
public CustomLocalCurrencyImageViewWhiteColor(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Glide.with(context).load(SessionManager.getCountryWiseDataObject(context).getCurrencyImageWhite()).into(this);
}
}
.Its working fine when I used it the following way
<com.kiran.example.ebitcoin.customview.CustomLocalCurrencyImageViewWhiteColor
android:id="#+id/img"
android:layout_width="#dimen/imageSizeTooSmallBTCLogo"
android:layout_height="#dimen/imageSizeTooSmallBTCLogo"
android:layout_gravity="center_vertical" />
Now, I want to change the image resource of this custom image too, dynamically, So I tried
CustomLocalCurrencyImageViewWhiteColor img = findViewById(R.id.img);
img.setImageResource(R.drawable.ic_bitcoin_24_white);
But unfortunately, nothing is changed. How to change the image of custom image view class dynamically?? Any one found answer of this?
Finally , I got answer of my own question. I follow this, and done the code by following way.
public class CustomLocalCurrencyImageViewWhiteColor extends AppCompatImageView {
Context context;
public CustomLocalCurrencyImageViewWhiteColor(Context context) {
super(context);
Glide.with(context).load(SessionManager.getCountryWiseDataObject(context).getCurrencyImageWhite()).into(this);
}
public CustomLocalCurrencyImageViewWhiteColor(Context context, AttributeSet attrs) {
super(context, attrs);
Glide.with(context).load(SessionManager.getCountryWiseDataObject(context).getCurrencyImageWhite()).into(this);
}
public CustomLocalCurrencyImageViewWhiteColor(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Glide.with(context).load(SessionManager.getCountryWiseDataObject(context).getCurrencyImageWhite()).into(this);
}
public void setImageWithGlide(Context context, Integer resId) {
this.context = context;
Glide.with(context).load("").placeholder(resId).into(this);
}
}
To change the image dynamically,
CustomLocalCurrencyImageViewWhiteColor img = findViewById(R.id.img);
img.setImageWithGlide(this, R.drawable.image);
As you are extending AppCompatImageView you can do as following:
Drawable drawable = AppCompatDrawableManager.get().getDrawable(getApplicationContext(), R.drawable.ic_bitcoin_24_white);
img.setImageResource(drawable);
Well u already use Glide in the first place, so try do it this way:
create setImageWithGlide method in CustomLocalCurrencyImageViewWhiteColor
public void setImageWithGlide(Context context, String imagePath) {
Glide.with(context).load(imagePath).into(this)
}
public void setImageWithGlide(Context context, Integer resId) {
Glide.with(context).load(resId).into(this)
}
you can use it like this:
img.setImageWithGlide(imagePath);
or if u use resourceId
img.setImageWithGlide(R.drawable.image);

Custom view (not ViewGroup) created based on xml layout (with predefined attributes)

I want to implement a custom ImageView with some predefined attributes based on the xml file. To do that I prepared a layout wrapped within merge tag:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="#+id/my_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:src="#drawable/icon" />
</merge>
And extended ImageView class:
public class CustomImageView extends LinearLayout{
public ImageFormField(Context context) {
super(context);
init();
}
public ImageFormField(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public ImageFormField(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public ImageFormField(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
View.inflate(getContext(), R.layout.custom_image_view, this);
}
}
It works so far, but I actually don't need that LinearLayout as I could extend directly from the ImageView. By extending ImageView I'd like to have the possibility to override src parameter from the default layout.
So I removed merge tag to have only ImageView in the layout and tried this:
public class CustomImageView extends AppCompatImageView{
public ImageFormField(Context context) {
super(context);
init();
}
public ImageFormField(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public ImageFormField(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
View.inflate(getContext(), R.layout.custom_image_view, null); //can't pass root here
}
}
... but the image is simply not displayed. I want to be able to use my view this way:
<com.my.package.CustomImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
with possibility to override src attribute. Is there a way to do that by inflating layout or do I have to go deep with attributes (including custom ones)?
UPDATE
By "overriding src attribute I mean that by default image will have source from its xml file, but user can use it that way to pass another value within this custom view:
<com.my.package.CustomImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/another_icon" />
To provide a "default" image but also allow the user to override that default by specifying the android:src attribute, you can do this:
package com.example.stackoverflow;
import android.content.Context;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
public class CustomImageView extends AppCompatImageView {
public CustomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
if (getDrawable() == null) {
setImageResource(R.drawable.default_image);
}
}
}
Then you can use it like this:
<!-- will display `default_image` -->
<com.example.stackoverflow.CustomImageView
android:layout_width="200dp"
android:layout_height="200dp"/>
Or:
<!-- will display `other_image` -->
<com.example.stackoverflow.CustomImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:src="#drawable/other_image"/>
There's no need to inflate anything inside the custom image view, and no need to create custom attributes (though you could certainly create custom attributes and use them if you wanted to).
You could update the Java code to apply other "default" styles too.

Change color Text from CustomTextView

By default to change textColor programatically is :
textView.setTextColor(Color.RED);
I need to have a custom Textview to change typeface and color by default, How can change textcolor from CustomTextView class, here is my code.
public class CustomTextView extends TextView {
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomTextView(Context context) {
super(context);
}
public void setTypeface(Typeface tf, int style) {
if(!isInEditMode()) {
if (style == Typeface.BOLD) {
super.setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/Lato-Bold.ttf"));
} else if(style == Typeface.ITALIC){ // constant used to set Lato-Light.
super.setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/Lato-Light.ttf"));
}else {
super.setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/Lato-Regular.ttf"));
}
}
}
The below code is the way to set your default text color and typeface.
public class CustomTextView extends TextView {
public CustomTextView(Context context) {
super(context);
init(context);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
setTypeface(Typeface.createFromAsset(context.getAssets(),"fonts/Lato-Light.ttf"));
setTextColor(Color.RED);
}
}
The init() method gets called every time the text view gets created, and will then set the typeface and color in that. You can manipulate any other variables you want to in there.
Use setTextColor(Color.RED); after each super in each constructor.
Step 1
In the /assets directory (not the /resource directory), create a folder called /fonts. Copy your custom font here. You can use both TTF and OTF fonts.
Step 2
In the /res/values folder, create a new file called attrs.xml. This is how the Android SDK lets you name custom properties for your widgets.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyTextView">
<attr name="fontName" format="string" />
</declare-styleable>
</resources>
Step 3
In /res/layouts, you will need to include your to-be-created custom text view in the activity_main.xml file.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:customfontdemo="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:padding="12dp"
android:text="Standard Android Font" />
<com.authorwjf.customfontdemo.MyTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="32sp"
android:padding="12dp"
customfontdemo:fontName="pipe_dream.ttf"
android:text="Custom Android Font" />
</LinearLayout>
Step 4
In the /src folder, you will want to create your MyTextView class. It extends the standard text view, plucks the font name from the custom attribute, and applies the type face.
package com.authorwjf.customfontdemo;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;
public class MyTextView extends TextView {
public MyTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public MyTextView(Context context) {
super(context);
init(null);
}
private void init(AttributeSet attrs) {
setTextColor(Color.RED);
if (attrs!=null) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MyTextView);
String fontName = a.getString(R.styleable.MyTextView_fontName);
if (fontName!=null) {
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/"+fontName);
setTypeface(myTypeface);
}
a.recycle();
}
}
}
Step 5
Because the text view is now self-contained, you aren't required to make any modifications to our /src/MainAcitivity.java file.
package com.authorwjf.customfontdemo;
import android.os.Bundle;
import android.app.Activity;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

Android create custom NumberPicker widget

I'm using some simvot number picker in application, I want to create custom widget for that and use in all of project, now i'm create this files but I can not set any value for custom widget.
My attributes:
<declare-styleable name="CNumberPicker">
<attr name="maxValue" format="string" />
<attr name="minValue" format="string" />
<attr name="value" format="string" />
</declare-styleable>
My Custom NumberPicker widget:
public class CNumberPicker extends net.simonvt.numberpicker.NumberPicker implements OnClickListener {
private int maxValue;
private int minValue;
private int value;
public CNumberPicker(Context context) {
super(context);
}
public CNumberPicker(Context context, AttributeSet attrs) {
super(context, attrs);
processAttributeSet(attrs);
}
public CNumberPicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CNumberPicker, defStyle, 0);
processAttributeSet(attrs);
maxValue = Integer.parseInt(a.getString(R.styleable.CNumberPicker_maxValue));
minValue = Integer.parseInt(a.getString(R.styleable.CNumberPicker_minValue));
a.recycle();
setOnClickListener(this);
}
#Override
public void onClick(View v) {
}
private void processAttributeSet(AttributeSet attrs) {
this.setMaxValue(attrs.getAttributeIntValue(null, "maxValue", 0));
}
}
My defined widget into xml:
<com.sample.widget.CNumberPicker
android:id="#+id/np_choose_hour"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_weight="0.20"
android:gravity="center_horizontal"
app:maxValue="10"
app:minValue="1"
app:value="5">
</com.sample.widget.CNumberPicker>
how to set value defined into xml in layout?
You have to inflate the layout in code.
public CNumberPicker(Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.cnumberpicker, this);
}
presuming the layout file is cnumberpicker.xml
EDIT: These 3 functions are constructors. Any one of them could be called to construct the object. By using this instead of super we can force all constructors to end up calling the 3 parameter constructor. You need some cohesion here. You don't want to copy paste code every time you make one change.
public CNumberPicker(Context context) {
this(context, null);
}
public CNumberPicker(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CNumberPicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CNumberPicker, defStyle, 0);
processAttributeSet(attrs);
// this method allows a default value if no attributes are given. You should use them.
maxValue = Integer.parseInt(a.getString(R.styleable.CNumberPicker_maxValue,"10"));
minValue = Integer.parseInt(a.getString(R.styleable.CNumberPicker_minValue,"0"));
a.recycle();
}

Categories

Resources