I have set up a working custom list view array adapter code is almost similar to the one showed here (without the cache part)
now how do I change the font of all the items to something like roboto
edit
i tried this
added private Typeface textFont; before oncreate();
TextView yourTextView = (TextView) listAdapter.getView(0, null, null);
TypefacetextFont=Typeface.createFromAsset(getApplicationContext().getAssets(),"RobotoBoldCondensed.ttf");
yourTextView.setTypeface(textFont);
Create a folder in the root of your project called assets/fonts/ then paste the TTF font file (in this case roboto.ttf).
Then use that from your adapter's getview() method like this:
#Override
public View getView ( int position, View convertView, ViewGroup parent ) {
/* create a new view of my layout and inflate it in the row */
convertView = ( RelativeLayout ) inflater.inflate( resource, null );
/* Extract the city's object to show */
City city = getItem( position );
/* Take the TextView from layout and set the city's name */
TextView txtName = (TextView) convertView.findViewById(R.id.cityName);
txtName.setText(city.getName());
/* Take the TextView from layout and set the city's wiki link */
TextView txtWiki = (TextView) convertView.findViewById(R.id.cityLinkWiki);
txtWiki.setText(city.getUrlWiki());
Typeface face=Typeface.createFromAsset(getAssets(),"fonts/roboto.ttf");
txtName.setTypeface(face);
txtWiki.setTypeface(face);
return convertView;
}
EDIT :
Change this line,
TypefacetextFont=Typeface.createFromAsset(getApplicationContext().getAssets(),"RobotoBoldCondensed.ttf");
with,
textFont=Typeface.createFromAsset(getApplicationContext().getAssets(),"RobotoBoldCondensed.ttf");
in xml:
android:typeface
or in java:
setTypeface
Using Typeface you can change the font of your text, keep desire font ttf file in your assets folder, access and set to your desire view, just like below:
TextView txt = (TextView) findViewById(R.id.custom_font);
Typeface font = Typeface.createFromAsset(getAssets(), "roboto.ttf");
txt.setTypeface(font);
For more help check Quick Tip: Customize Android Fonts
Copy your font in to your assest folder and put this code inside of your custom array adapter
TextView yourTextView = (TextView)findViewById(R.id.yourid);
Typeface textFont = Typeface.createFromAsset(context.getAssets(),"YourFont.ttf");
yourTextView.setTypeface(textFont);
It should work.
EDIT
private Typeface textFont;
Declare
#Override
public void onCreate(){
textFont = Typeface.createFromAsset(context.getAssets(),"YourFont.ttf"); }
in OnCreate() or OnStart()
and just use your custom font in your getView()
yourTextView.setTypeface(textFont);
Related
So I have a messaging app where I read my database and render all the messages programatically. The thing is, when I am inside a different layout, I need to inflate those messages and edit them at will. For example,
val myView = inflater.inflate(R.layout.female_messaging_fragment, container, false)
...
val convLayout = myView.findViewById<LinearLayout>(R.id.conversations_layout)
val profileLayout = LinearLayout(context)
val recentMessage = TextView(context)
recentMessage.id = 5
val recentParams = LinearLayout.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT)
recentParams.setMargins(10, 0, 0, 0)
recentMessage.layoutParams = recentParams
recentMessage.textSize = 16f
if (didIsendLastMessage) {
val arrowIcon = ImageView(context)
Picasso.get().load(R.drawable.right_arrow).resize(50, 50).into(arrowIcon)
val imageParams = LinearLayout.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT)
imageParams.gravity = Gravity.CENTER
arrowIcon.layoutParams = imageParams
recentMessage.setText(mostRecentMessage)
arrowAndMessageLayout.addView(arrowIcon)
arrowAndMessageLayout.addView(recentMessage)
} else {
recentMessage.setText(mostRecentMessage)
arrowAndMessageLayout.addView(recentMessage)
}
nameLastmessageLayout.addView(arrowAndMessageLayout)
// Add namne and message to profile
profileLayout.addView(nameLastmessageLayout)
convLayout.addView(profileLayout)
And then in a different layout...
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.female_messaging_fragment, null);
TextView text = (TextView) v.findViewById(5);
text.setText("Something");
The thing is, text is always null, and I believe it is because I added the views programatically. What else can I do here? Thanks!
inflating female_messaging_fragment will return fresh new Layout view object of your xml that might be blank layout without any TextViews.
To get TextView object you need the object of Layout in which you had added the views.
For example as per your code you added recentMessage in arrowAndMessageLayout so to get the object of recentMessage you need the object of arrowAndMessageLayout and can get like below -
TextView text = arrowAndMessageLayout.findViewById(5);
OR
TextView text = convLayout.findViewById(5);
Inflating again will return fresh new container without your textview.
Hope this will help you.
I have an ArrayList<String> like this [Angularjs, JavaScript, Css]
In my Adapter where I get the ArrayList of tags from another Intent. I tried to display all the elements of the ArrayList as Chips with the below approach, but I get only the last element of the ArrayList. I only see one Chip with the last element of the ArrayList.
for (String tag: card.getTags()) {
Log.d(TAG, "tag - " + tag);
holder.tags.setText(tag);
}
Could anyone please guide, how do I change my code to display all the elements of the ArrayList as Chips.
If you are talking about Chips.
Add a ChipGroup in xml layout where you want to show your chips
<com.google.android.material.chip.ChipGroup
android:id="#+id/chipGroup"
android:layout_width="match_parent"
app:chipSpacingVertical="2dp"
android:layout_height="wrap_content"/>
Now you can use this method to add your ArrayList as Chip in ChipGroup :
private void addChip(String pItem, ChipGroup pChipGroup) {
Chip lChip = new Chip(this);
lChip.setText(pItem);
lChip.setTextColor(getResources().getColor(R.color.primary_text));
lChip.setChipBackgroundColor(getResources().getColorStateList(R.color.chip_bg));
pChipGroup.addView(lChip, pChipGroup.getChildCount() - 1);
}
Currently, you're replacing tags in your forEach Loop of the holder. You have only one holder and keep updating that till loop ends; that's the reason you have last chip/tag
If you are referring to ChipGroup of MaterialComponents.
ChipGroup chipGroup = new ChipGroup(parentView.getContext());
String[] genres = {"Thriller", "Comedy", "Adventure"};
for(String genre : genres) {
Chip chip = new Chip(parentView.getContext());
chip.setText(genre);
chipGroup.addView(chip);
}
I assume you must be using RecyclerView as I see the holder in your snippet.
Following is the view hierarchy; I am assuming you are trying to achieve; if not then you can use the same line of logic to move around those pieces
RecyclerView
Each Item/View
Tags - Multiple Tag using FlowLayout - Adding multiple tags in view
You need to bind each item in your RecyclerView.
#Override
public void onBindViewHolder(final YourViewHolder holder, final int position) {
...
// assuming you have FlowLayout in recyclerview view item
// do add holder pattern to flowlayout as well
fillAutoSpacingLayout(card.getTags(), holder.flowLayout);
}
Here I'm using FlowLayout to add chips or tags inside each view of RecyclerView.
Binding each item/View inside onBindViewHolder:
private void fillAutoSpacingLayout(ArrayList<String> tags, FlowLayout flowLayout) {
for (String tag : tags) {
TextView textView = buildLabel(tag);
flowLayout.addView(textView);
}
}
private TextView buildLabel(String text) {
TextView textView = new TextView(this);
textView.setText(text);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
textView.setPadding((int)dpToPx(16), (int)dpToPx(8), (int)dpToPx(16), (int)dpToPx(8));
textView.setBackgroundResource(R.drawable.label_bg);
return textView;
}
private float dpToPx(float dp){
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
Moreover, you can refer to this SO question as it's on the same lines.
I have an EditText inside of a RelativeLayout (named TopLayout in code below) that is inside of a ListView. There is TextWatcher on the EditText that changes the height of the RelativeLayout (and ListView). But when the height changes, the cursor inside of the EditText moves to the beginning.
Is there anyway to get it to stay where it is?
public void setItemHeight(int itemPos, int itemHeight) {
if (mChallengingThoughtsListView != null) {
View itemView = mChallengingThoughtsListView.getChildAt(itemPos);
LinearLayout topLayout = itemView.findViewById(R.id.TopLayout);
// Set item height
ViewGroup.LayoutParams params = topLayout.getLayoutParams();
params.height = itemHeight;
topLayout.setLayoutParams(params);
// TODO: Put code to place cursor back where it was
}
}
I have an activity that displays a listview of html links, each stored in a TextView, that the user can add and remove links from by specifying a name and web address. Each link is stored in the listview in HTML, as below, and the user would click the word 'google' to start the web browser.
<a href='http://www.google.com'>google</a>
I have tried several ways to make the links do this, including android:autolink="web" in the XML file, with the method below being the only way that works. However, I cannot call it as the activity is initializing (from onCreate() or onStart()) as the getChildAt method returns null.
TextView wantedView = (TextView) listView.getChildAt(i);
wantedView.setText(Html.fromHtml(s));
wantedView.setClickable(true);
wantedView.setMovementMethod(LinkMovementMethod.getInstance());
However, if I set a clickable button that calls this code, then it works, although adding a new link to the list reverts the formatting.
Does anybody know why I can't access the TextView objects while initializing, and if there is another way to do this? I've posted my layout file and listview start up code below.
simplerow.xml <TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rowTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="15sp"
android:visibility="visible"
android:autoLink=""
android:gravity="center">
listview.xml <ListView
android:id="#+id/listView1"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test2);
listView1 = (ListView) findViewById(R.id.listView1);
items = new String[]{ "<a href='http://www.facebook.com'>facebook</a>",
"<a href='http://www.google.com'>google</a>",
"<a href='http://www.twitter.com'>twitter</a>" };
list = new ArrayList<>();
for(int i=0; i<items.length; i++) {
list.add(items[i]);
}
adapter = new ArrayAdapter<String>(Test.this, R.layout.simplerow, list);
listView1.setAdapter(adapter);
makeLinksVisible();
}
private void makeLinksVisible() {
int i = 0;
TextView wantedView = (TextView) listView.getChildAt(i);
while (wantedView != null) {
String s = wantedView.getText().toString();
wantedView.setText(Html.fromHtml(s));
wantedView.setClickable(true);
wantedView.setMovementMethod(LinkMovementMethod.getInstance());
i++;
wantedView = (TextView) listView.getChildAt(i);
}
}
Let you create the class extending ArrayAdapter<String>, and then override the getView(...) method. There you will have to have a LayoutInflatter and a View that refer to a single row (simply named row). This is the best place to execute row.setOnClickListener(new View.OnClickListener() {/*...*/}. Do not forget to create a holder if you will have a lot of displayed at once data.
More about custom ArrayAdapters e.g. here
The solution is to get the TextView from your ArrayAdapter, not your ListView. So if you are using a ListActivity, you would do something like:
ListView listView = getListView();
ArrayAdapter arrayAdapter = listView.getAdapter();
FrameLayout frameLayout = (FrameLayout) arrayAdapter.getView(0, null, null);
TextView wantedView = (TextView) frameLayout.findViewById(R.id.your_text_view);
wantedView.setText(Html.fromHtml(s));
wantedView.setClickable(true);
wantedView.setMovementMethod(LinkMovementMethod.getInstance());
This code of course assumes the use of a FrameLayout, but you would just replace that with whatever parent container holds your TextView that you are trying to access. Then in the getView() method, you would pass in the position of your TextView (I used zero just for an example). But if you try and use this code in your onCreate() it should work.
For any future viewers, here is a solution to the problem, and a brief description of how I found it.
I tried drschultz solution and noticed no change. He commented that using a textview with a string resource works. I tried this and realised the listview needed to be passed Spanned objects.
I found a solution for creating a Spanned Listview - here - and then added an onItemClickListener, which called setMovementMethod on the Textview object provided.
I realised that the previous solution wasn't working because the adapter's 'getview' method wasn't providing a reference to the listview object, instead it was providing a copy with the same data (I think). Overriding the onItemClick method is a quick solution to get a reference to the list object, which allows you to manipulate it directly and do whatever you like to it.
I've added the code I used to test this solution below. It creates a list of two html references. The first click of a textview calls the onItemClick method, then any more clicks will take you to the web page specified.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
String s = new String("facebook");
Spanned sp = Html.fromHtml(s);
String s1 = new String("google");
Spanned sp1 = Html.fromHtml(s1);
listValues = new ArrayList<>();
listValues.add(sp);
listValues.add(sp1);
setListAdapter(new SpannedAdapter(this, listValues));
ListView l = getListView();
l.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
try {
LinearLayout linearLayout = (LinearLayout) view;
TextView wantedView = (TextView) linearLayout.findViewById(R.id.rowTextView);
wantedView.setClickable(true);
wantedView.setMovementMethod(LinkMovementMethod.getInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
I get a null pointer exception at line five/seven of my code:
LayoutInflater inflater = getLayoutInflater();
View header = inflater.inflate(R.layout.footer_row, (ViewGroup) findViewById(R.id.header_layout_root));
TextView tv_footer = (TextView) findViewById(R.id.tv_footertext);
if(getListView().getCount()<=8) {
tv_footer.setText("You have no more assignments");
} else {
tv_footer.setText(Integer.toString(getListView().getCount()) + " assignments shown");
}
getListView().addFooterView(header, null, false);
I'm not too sure why, so could you tell me? List view's aren't my thing.
I'll tick the right answer!
Instead of using the findViewById() method from your Activity's View you should assign (which I assume is the footer TextView in your R.layout.footer_row) the TextView from the inflated View.
Sample code:
TextView tv_footer = (TextView) header.findViewById(R.id.tv_footertext);
Change third line of your code as specified below. as your inflated view contains the textView you specified.
TextView tv_footer = (TextView) header.findViewById(R.id.tv_footertext);
Thanks.
can you post the logcat information,it seems that tv_footer value may not set,It may be R.id.tv_footertext is not the part of layout which you set in the setContentView(....) method check it once.It is better if you provide code in detail(since your posted code seems fine)