Custom TextView font not applied on setting text from java android - java

I have created a Custom TextView to use Font Awesome support, its working fine when you add the text (unicode ) in layout xml. But if am trying to set the text from my Adapter dynamically using view.setText(), its not applying the font.
FontView class
public class FontView extends TextView {
private static final String TAG = FontView.class.getSimpleName();
//Cache the font load status to improve performance
private static Typeface font;
public FontView(Context context) {
super(context);
setFont(context);
}
public FontView(Context context, AttributeSet attrs) {
super(context, attrs);
setFont(context);
}
public FontView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setFont(context);
}
private void setFont(Context context) {
// prevent exception in Android Studio / ADT interface builder
if (this.isInEditMode()) {
return;
}
//Check for font is already loaded
if(font == null) {
try {
font = Typeface.createFromAsset(context.getAssets(), "fontawesome-webfont.ttf");
Log.d(TAG, "Font awesome loaded");
} catch (RuntimeException e) {
Log.e(TAG, "Font awesome not loaded");
}
}
//Finally set the font
setTypeface(font);
}
}
XML for Layout
<com.domain.app.FontView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="60sp"
android:textAlignment="center"
android:text=""
android:gravity="center"
android:id="#+id/iconView"
android:background="#drawable/oval"
android:padding="10dp"
android:layout_margin="10dp" />
My Adapter
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
IconListHolder viewHolder;
if( convertView == null ) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = layoutInflater.inflate(R.layout.icon, null);
viewHolder = new IconListHolder(v);
v.setTag(viewHolder);
} else {
viewHolder = (IconListHolder) v.getTag();
}
//Set the text and Icon
viewHolder.textViewIcon.setText(pages.get(position).getIcon());
viewHolder.textViewName.setText(pages.get(position).getTitle());
return v;
}
private class IconListHolder {
public FontView textViewIcon;
public TextView textViewName;
public IconListHolder(View base) {
textViewIcon = (FontView) base.findViewById(R.id.iconView);
textViewName = (TextView) base.findViewById(R.id.iconTextView);
}
}
Please help whats am doing wrong.

After struggling more than 3 hrs. I have found the answer here. It was unicode issue.
Changing Adapter setText() to use Html.fromHtml("").toString() fixed the issue
viewHolder.textViewIcon
.setText(Html.fromHtml(pages.get(position).getIcon()).toString());
Read more here
I hope you guys find it useful.

Could not find an error of your code.
This the custom textView which I'm using. Create font folder inside your assets folder
CustomText.java
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;
public class CustomText extends TextView {
public CustomText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
public CustomText(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public CustomText(Context context) {
super(context);
init(null);
}
private void init(AttributeSet attrs) {
if (attrs!=null) {
{
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(),"fonts/custom_font.ttf");
setTypeface(myTypeface);
}
}
}
}

Related

when initializing view in fragment i got a nullpointerException at getcontext() [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I'm initialing imageview at DailyCardView.java which are called by a fragment. But it keeps showing nullPointerException. I really don't know where went wrong... Guys help me><
I tried getRootView() to get view of Fragment so i can code:iv=(ImageView)getRootView().findViewById(R.id.iv);
But it still not work.
**//Fragment**
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.home_fragment, container, false);
dailyStackLayout = (DailyStackLayout)view.findViewById(R.id.dailyStackLayout);
dailyStackLayout.setDatas(dailyFoodList);
return view;
}
**//DailyStackLayout**
public DailyStackLayout(Context context) {
this(context, null);
}
public DailyStackLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DailyStackLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public void init() {
params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
scaleY = DensityUtil.dip2px(getContext(), BASESCALE_Y_VALUE);
}
public void setDatas(List<DailyFood> dailyFoodList) {
this.dailyFoodList = dailyFoodList;
if (dailyFoodList == null) {
return;
}
for (int i = index; index < i + STACK_SIZE; index++) {
dc = new DailyCardView(getContext());
dc.bind(dailyFoodList.get(index));
}
}
**//DailyCardView**
public DailyCardView(Context context) {
super(context, null);
}
public DailyCardView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public DailyCardView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
init(context);
}
public void init(Context context) {
if (!isInEditMode()) {
inflate(context, R.layout.item_daily_card, this);
iv = (ImageView)findViewById(R.id.iv);
}
}
public void bind(DailyFood dailyFood) {
if (dailyFood == null) {return;}
if (!TextUtils.isEmpty(dailyFood.getId())) {
Glide.with(**iv.getContext()**) // **NullPointerException**!
.load(Constant.Daily_URL+dailyFood.getId()+".jpg")
.into(iv);
}
I expect to load the image right but it went wrong at getContext().
dc = new DailyCardView(getContext());
This calls the DailyCardView(Context) constructor that does not call init():
public DailyCardView(Context context) {
super(context, null);
}
The init() call would init iv. And then you call bind() that assumes that iv is initialised. Bang, NPE.
Either change the super in the constructor to this to delegate to another constructor that calls init(), or just add a call to init().

Android - Custom Dialog

I'm trying to create a custom dialog where the content inside the dialog is dynamic. So I pass a view to the dialog and it will add that view to the dialog. Currently, it doesn't draw the custom view and its saying that the view has a width and height of 0.
I pass the custom view through the Application class along with a bunch of other customizations.
Here is my dialog class:
public class LoadingActivity extends Dialog
{
private LoadingActivity(Context a) {
super(a, android.R.style.Theme);
}
public static LoadingActivity show(Context context) {
LoadingActivity checkerLoader = new LoadingActivity(context);
View currentView = View.inflate(context, R.layout.loading_activity, null);
FrameLayout linearLayout = (FrameLayout) currentView.findViewById(R.id.circular_progress_bar);
RelativeLayout viewLayout = (RelativeLayout) currentView.findViewById(R.id.view_layout);
if (DataManager.getInstance().getAppConfigurations().getLoadingActivity() != null) {
View loadingView = DataManager.getInstance().getAppConfigurations().getLoadingActivity();
loadingView.setBackgroundColor(Color.RED);
loadingView.invalidate();
if(loadingView.getParent()!=null) {
((ViewGroup) loadingView.getParent()).removeView(loadingView);
}
viewLayout.addView(loadingView);
}
checkerLoader.requestWindowFeature(Window.FEATURE_NO_TITLE); //before
checkerLoader.setContentView(currentView);
checkerLoader.setCancelable(false);
checkerLoader.getWindow().getAttributes().gravity = Gravity.CENTER;
WindowManager.LayoutParams lp = checkerLoader.getWindow().getAttributes();
lp.dimAmount=0.2f;
checkerLoader.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
checkerLoader.getWindow().setAttributes(lp);
checkerLoader.show();
return checkerLoader;
}
}
Heres an example of my custom view:
public class Spinner extends LinearLayout
{
public Spinner(Context context) {
super(context);
init(context);
}
public Spinner(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public Spinner(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
View aView = View.inflate(context, R.layout.loading_activity, null);
ImageView logoImage = (ImageView) aView.findViewById(R.id.loading_image);
logoImage.setImageResource(R.drawable.loading_chicken2);
}
}
The Custom View Spinner doesn't draw anything cause the inflated layout 'R.layout.loading_activity' isn't added to a parent .
changing
View aView = View.inflate(context, R.layout.loading_activity, null);
to:
View aView = View.inflate(context, R.layout.loading_activity, this);
might help

How to add RecyclerView to a View

I have a custom view extends RelativeLayout, and I want to add a RecyclerView in it. But the recyclerView can't be shown.
How to solve it? Thanks!
The code:
LineChart.java
public class LineChart extends RelativeLayout {
RecyclerView mRecyclerView;
public LineChart(Context context) {
super(context);
init(context, null);
}
public LineChart(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public LineChart(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
protected void init(Context context, #Nullable AttributeSet attrs) {
setWillNotDraw(false);
initInside();
}
protected void initInside() {
View v = inflate(getContext(), R.layout.line_chart_recyclerview, null);
LineChart.LayoutParams params = new LineChart.LayoutParams(
getWidth() / 2, getHeight());
params.addRule(LineChart.ALIGN_PARENT_RIGHT);
addView(v, params);
mRecyclerView = (RecyclerView) findViewById(R.id.lineChartRecyclerView);
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("World");
list.add("~~~");
LineChartAdapter lineChartAdapter = new LineChartAdapter(getContext(),
list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.setAdapter(lineChartAdapter);
}
#Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
}
LineChartAdapter.java
public class LineChartAdapter
extends RecyclerView.Adapter<LineChartViewHolder> {
private List<String> mList;
private Context mContext;
public LineChartAdapter(Context context, List<String> list) {
this.mContext = context;
this.mList = list;
}
#Override
public LineChartViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mContext)
.inflate(R.layout.item_line_chart, parent,
false);
return new LineChartViewHolder(itemView);
}
#Override
public void onBindViewHolder(LineChartViewHolder holder, int position) {
holder.mTextView.setText(String.valueOf(position));
}
#Override public int getItemCount() {
return mList == null ? 0 : mList.size();
}
}
LineChartViewHolder.java
public class LineChartViewHolder extends RecyclerView.ViewHolder {
protected TextView mTextView;
public LineChartViewHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView.findViewById(
R.id.text1024);
}
}
I think, I know the reason.
View v = inflate(getContext(), R.layout.line_chart_recyclerview, null);
LineChart.LayoutParams params = new LineChart.LayoutParams(
getWidth() / 2, getHeight());
params.addRule(LineChart.ALIGN_PARENT_RIGHT);
addView(v, params);
Here, getWidth() and getHeigth() are still 0. So your view will have (0;0) size
To fix this, I'd suggest to replace this part with
LayoutInflater.from(context).inflate(R.layout.line_chart_recyclerview, this);
Let me know, if it helps.

How to use custom font in custom BaseAdapter

I am creating an Android app using Android Studio.
I have listview in an activity that is using a custom SimpleAdapter.
I need to use a custom font in the custom adapter but when I try it does not work.
No errors only no font is being used. The font path works fine when used directly in an activity.
When I log out the fonter created I get this:
E/====﹕ FONT: android.graphics.Typeface#4c5dfbc0
This is my custom adapter code:
package com.myapp.app.utilities;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import com.fieldly41.app.R;
import java.util.ArrayList;
import java.util.HashMap;
public class SimpleIconAdapter extends SimpleAdapter {
private ArrayList<HashMap<String, String>> results;
//private Context context;
Typeface font;
public SimpleIconAdapter(Context context, ArrayList<HashMap<String, String>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.results = data;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
View v = view;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.list_item_icon, null);
}
if(results.get(position) != null ) {
Typeface fonter = Typeface.createFromAsset(v.getResources().getAssets(), "fonts/ss-symbolicons-line.ttf");
TextView top_label = (TextView) v.findViewById(R.id.top_label);
TextView icon_label = (TextView) v.findViewById(R.id.icon);
TextView bottom_label = (TextView) v.findViewById(R.id.bottom_label);
icon_label.setText("💀");
icon_label.setTypeface(fonter);
if (results.get(position).get("locked").equals("false")) {
icon_label.setTextColor(Color.WHITE);
} else {
icon_label.setTextColor(Color.RED);
}
top_label.setText(results.get(position).get("title"));
bottom_label.setText(results.get(position).get("created_at"));
}
return v;
}
}
Your implementations is near to ok.
But the big problem is you are creating a TypeFace instance in getView() method which is very resource hungry.
Because getView() method calls repeatedly N numbers of time whenever you scroll the list.
And loading resource from assets extensively is bad practice, it may cause OutOfMemoryError any time.
So my recommendation is create common object and use in getView().
public SimpleIconAdapter(Context context, ArrayList<HashMap<String, String>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
font=Typeface.createFromAsset(context.getAssets(), "fonts/ss-symbolicons-line.ttf");
this.results = data;
}
In getView() remove this Line
Typeface fonter = Typeface.createFromAsset(v.getResources().getAssets(), "fonts/ss-symbolicons-line.ttf");
And use "font" object instead fonter
icon_label.setTypeface(font);
Try this way,hope this will help you to solve your problem.
Since it's a listview, I would suggest you to create a custom textview and take it inside the row layout xml.
Note: It's important that you place required font files in the assets folder.
Create Custom TextView with your custom font.
CustomTextView.java
public class CustomTextView extends TextView {
public CustomTextView(Context context) {
super(context);
setFont();
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setFont();
}
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFont();
}
private void setFont() {
Typeface font = Typeface.createFromAsset(getContext().getAssets(),"fonts/ss-symbolicons-line.ttf");
setTypeface(font, Typeface.NORMAL);
}
}
Try define Custom TextView instead of simple TextView which you would like to shown your custom font.
list_item_icon.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/top_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<yourpackagename.CustomTextView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"/>
<TextView
android:id="#+id/bottom_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"/>
</LinearLayout>
Care about Custom TextView declaration and initialization and try to use ViewHolder concept when you use Custom adapter.
public class SimpleIconAdapter extends SimpleAdapter {
private Context context;
private ArrayList<HashMap<String, String>> results;
public SimpleIconAdapter(Context context, ArrayList<HashMap<String, String>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.results = data;
this.context=context;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = LayoutInflater.from(context).inflate(R.layout.list_item_icon, null);
holder.top_label = (TextView) view.findViewById(R.id.top_label);
holder.icon_label = (CustomTextView) view.findViewById(R.id.icon);
holder.bottom_label = (TextView) view.findViewById(R.id.bottom_label);
view.setTag(holder);
}else{
holder = (ViewHolder) view.getTag();
}
holder.icon_label.setText("💀");
if (results.get(position).get("locked").equals("false")) {
holder.icon_label.setTextColor(Color.WHITE);
} else {
holder.icon_label.setTextColor(Color.RED);
}
holder.top_label.setText(results.get(position).get("title"));
holder.bottom_label.setText(results.get(position).get("created_at"));
return view;
}
class ViewHolder{
TextView top_label;
CustomTextView icon_label;
TextView bottom_label;
}
}

Animate last added child in Grid View with Adapter

I have a GridView which I am constantly adding views to. When the view adds to the grid I wish for it to do an animation. However, as I have to use setAdapter() to refresh the GridView, it ends up animating all views, as they are all being re-added. Is there anyway around this?
Here is the code for my view I am adding:
public class GridImageView extends ImageView {
public GridImageView(Context context) {
super(context);
}
public GridImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GridImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
ScaleAnimation anim = new ScaleAnimation(0,1,0,1);
anim.setDuration(1000);
anim.setFillAfter(true);
this.startAnimation(anim);
}
}
As always, thanks for your help
Thanks to Luksprog's suggestion, I have set a flag in my custom view which will determine if the view should animate when added to the Grid View.
public class GridImageView extends ImageView
{
private boolean _animate = false;
public GridImageView(Context context) {
super(context);
}
public GridImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GridImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onAttachedToWindow() {
if(_animate){
super.onAttachedToWindow();
ScaleAnimation anim = new ScaleAnimation(0,1,0,1);
anim.setDuration(1000);
anim.setFillAfter(true);
this.startAnimation(anim);
}
}
public void set_animate(boolean _animate) {
this._animate = _animate;
}
}
and my adapter in its GetView() function checks if it is the last in the array list, and sets the flag to true if so.
if( i == ( _gridDetailsArrayList.size() - 1 ))
holder.gridImage.set_animate(true);

Categories

Resources