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);
Related
I have a xml layout with an element i use multiple times... so i decided to use <include> in the xml to avoid excess code.
My problem is that i want to make a class that is connected to this included xml component and reference to it, rather than writing the same code multiple times.
I tried to read up on a custom view component and created a class ParcelPopbarView:
public ParcelTopBarView extends View {
/...
public ParcelTopBarView(Context context, ParcelListItem parcelListItem) {
super(context);
this.parcelListItem = parcelListItem;
this.context = context;
titleTextView = findViewById(R.id.title_textview);
subtitleTextView = findViewById(R.id.subtitle_textview);
deliveryInfoTextView = findViewById(R.id.delivery_info_textview);
thumbnailLogo = findViewById(R.id.thumbnail_logo);
}
public void setTopbar(){
titleTextView.setText("hello!");
}
But i felt like custom views mostly is about drawing on a canvas, i am not doing that... so i dont know if using view is right either.
Either way, the titleTextView is null cause it cannot find the refrence to the xml file, and i have no idea how to reference to it hahah.
Does anyone have a smart solution to how i can do this the right way?
You need to inflate the layout for all the constructors of your custom view to be able to access them later.
public class ParcelTopBarView extends View {
public ParcelTopBarView(Context context) {
super(context);
init();
}
public ParcelTopBarView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public ParcelTopBarView(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public ParcelTopBarView(Context context, #Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
View view = inflate(getContext(), R.layout.parcel_top_bar, this);
titleTextView = findViewById(R.id.title_textview);
subtitleTextView = findViewById(R.id.subtitle_textview);
deliveryInfoTextView = findViewById(R.id.delivery_info_textview);
thumbnailLogo = findViewById(R.id.thumbnail_logo);
}
I am trying to show hand pointer icon which is https://fontawesome.com/icons/hand-pointer?style=regular I want to show it solidly(white background) like this one https://fontawesome.com/icons/hand-pointer?style=solid .
But here I have a problem that both of them has the same unicode which is f25a.
//This is the FontAwesomeTextView I Created
FontAwesomeTextView fingerPointer = new FontAwesomeTextView(MyApplication.getStaticContext());
fingerPointer.setText(MyApplication.getStaticContext().getString(R.string.finger_pointer));
fingerPointer.setTextColor(ContextCompat.getColor(MyApplication.getStaticContext(), R.color.colorWhite));
fingerPointer.setShadowLayer(2,2,2,R.color.colorOrange);
fingerPointer.setTextSize(30f);
fingerPointer.setVisibility(View.GONE);
this.fingerPointer = fingerPointer;
//This is the hand pointer text that I am using
<string name="finger_pointer" translatable="false"></string>
As you can see icon i send in link has the same unicode in string.xml.
This is my FontAwesomeTextView which is pretty simple class that loads fontawesome typeface and set it.
public class FontAwesomeTextView extends AppCompatTextView {
public FontAwesomeTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public FontAwesomeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public FontAwesomeTextView(Context context) {
super(context);
init();
}
private void init() {
Typeface typeface = FontCache.get(FontCache.FONT_AWESOME,getContext());
setTypeface(typeface);
}
}
i have the following code, and the problem, that my function rlposition() isn't available from outside the class.
public class RLbadge extends TextView {
public RLbadge(Context context) {
super(context);
this.setTypeface(null, Typeface.BOLD);
this.setTextColor(Color.WHITE);
this.setBackgroundResource(R.drawable.badge);
this.setTextSize(18);
}
public void rlposition(Button pButton) {
// THIS FUNCTION ISNT SEEN FROM OUTSIDE WHY?
}
protected void onDraw (Canvas canvas) {
super.onDraw(canvas);
}
}
Why is the function rlposition not visible from outside of the class?
Isn't it possible to add functionality to an extended TextView?
<YOURPACKAGENAME.MyTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="32sp"
android:text="TEASTING" />
Here is Class
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) {
// Do your staff
}
}
}
i now answered the question for myself and put it here maybe somebody needs the answer in the future.
The problem was this line of calling:
TextView badgeInfoscan = new RLbadge(this);
badgeInfoscan.rlposition(); // here the error comes
changed to
RLbadge badgeInfoscan = new RLbadge(this);
badgeInfoscan.rlposition(); // the function is visible
I am building a custom View that requires as one of its Attributes a Class<> object to an entity. While I made it work programmatically by adding a Setter for it, I was wondering if there is any good way to allow adding it to the XML for the layout as well?
There does not appear to be a format option for a styleable with type "class". I could use a String, but then I'd have to gamble that the value is actually a valid Class and I'd lose type hinting, so it'd not be ideal.
Is there any good way to make this work, or should I just stick with setting it programmatically?
Method 1 (With warnings):
Generic CustomView:
public class CustomView<T> extends View {
private List<T> typedList = new ArrayList<T>();
public CustomView(Context context) {
this(context, null);
}
public CustomView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void addTypedValue(T object){
typedList.add(object);
}
public T getTypedValue(int position){
return typedList.get(position);
}
}
Activity:
//unsafe cast!
CustomView<String> customViewGeneric = (CustomView<String>) findViewById(R.id.customView);
customViewGeneric.addTypedValue("Test");
String test = customViewGeneric.getTypedValue(0);
XML:
<org.neotech.test.CustomView
android:id="#+id/customView"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
Method 2 (No warnings, safe!):
This method uses a generic CustomView. And for each type that will be used in xml you will need to create a specific class.
I have added an example implementation:
Generic CustomView: (Do not inflate this one in xml):
public class CustomView<T> extends View {
private List<T> typedList = new ArrayList<T>();
public CustomView(Context context) {
this(context, null);
}
public CustomView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void addTypedValue(T object){
typedList.add(object);
}
public T getTypedValue(int position){
return typedList.get(position);
}
}
XML inflatable view for the String type:
public class CustomViewString extends CustomView<String> {
//ADD Constructors!
}
XML inflatable view for the Integer type:
public class CustomViewInteger extends CustomView<Integer> {
//ADD Constructors!
}
Activity:
CustomViewString customViewString = (CustomViewString) findViewById(R.id.customViewString);
CustomView<String> customViewGeneric = customViewString;
XML:
<org.neotech.test.CustomViewString
android:id="#+id/customViewString"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<org.neotech.test.CustomViewInteger
android:id="#+id/customViewInteger"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
I'm trying something like this
public class CustomViewSubclass extends HorizontalScrollView{
private LinearLayout layout;
public CustomViewSubclass(Context context) {
this(context,null,0);
}
public CustomViewSubclass(Context context, AttributeSet attrs) {
this(context,attr,0);
}
public CustomViewSubclass(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
layout = new LinearLayout(context);
}
// This is called from the `Activity`
public void startAsyncTask() { // code }
// This method is called in the `onPostExecute()` of an `AsyncTask` subclass
public void doSomething(Context context) {
ImageView image = ImageView(context);
layout.addView(image); // NullPointerException here, layout seems to be null
}
but it seems that layout on doSomething() is null. How is that even possible? I'm initializing it on the constructor... and I never re-initialize it again;
I'm adding my custom view via XML
<com.mypackage.CustomViewSubclass
android:layout_width="wrap_content"
android:layout_width="match_parent" />
Ok I fixed it, it was an stupid mistake made by me:
I used super() on the 3 methods, instead of using this().
public CustomViewSubclass(Context context) {
super(context,null,0);
}
public CustomViewSubclass(Context context, AttributeSet attrs) {
super(context,attr,0);
}
public CustomViewSubclass(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
layout = new LinearLayout(context);
}
Solution:
public CustomViewSubclass(Context context) {
this(context,null,0);
}
public CustomViewSubclass(Context context, AttributeSet attrs) {
this(context,attr,0);
}
public CustomViewSubclass(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
layout = new LinearLayout(context);
}