I am trying to use custom font in my ListView adapter, but I am doing something wrongly.
I tried to use getAssets and getContext, but I can't use them in my app.
I hope that maybe someone can help me find the solution.
Adapter code in Java, as shown below:
public class ListviewAdapter extends BaseAdapter {
private LayoutInflater mLayoutInflater;
private ArrayList<Cwiczenie> listaCwiczen;
public ListviewAdapter(Context context, ArrayList<Cwiczenie> data) {
mLayoutInflater = LayoutInflater.from(context);
listaCwiczen = data;
}
#Override
public int getCount() {
return listaCwiczen == null ? 0 : listaCwiczen.size();
}
#Override
public Cwiczenie getItem(int position) {
return listaCwiczen.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
View vi = view;
ViewHolder holder = null;
if (vi == null) {
vi = mLayoutInflater.inflate(R.layout.wierszlisty, parent, false);
holder = new ViewHolder();
holder.tvName = (TextView) vi.findViewById(R.id.nazwa_cwiczenia);
// holder.tvDescription = (TextView)
// vi.findViewById(R.id.textView_item_description);
vi.setTag(holder);
} else {
holder = (ViewHolder) vi.getTag();
}
Cwiczenie cwiczenie = getItem(position);
holder.tvName.setText(cwiczenie.getNazwa());
// holder.tvDescription.setText(item.getDescription());
return vi;
}
static class ViewHolder {
TextView tvName;
// TextView tvDescription;
}
}
holder.tvName = (TextView) vi.findViewById(R.id.nazwa_cwiczenia);
below this use this code:
Typeface tf = Typeface.createFromAsset(vi.getContext().getAssets(), "font/chiller.ttf");
holder.tvName.setTypeface(tf);
create a "font" folder inside assets folder and place your font file there. Instead of "chiller.ttf" write your font file name.
This code worked for me. I hope it will work for you too.
keep a reference to Typeface, as member variable, and initialize it in the constructor of your adapter:
Typeface tf;
public ListviewAdapter(Context context, ArrayList<Cwiczenie> data) {
tf = Typeface.createFromAsset(context.getAssets(),"fonts/yourfonts.ttf");
// other code
}
in getView() when you instantiate your row, assign the font
if (vi == null) {
vi = mLayoutInflater.inflate(R.layout.wierszlisty, parent, false);
holder = new ViewHolder();
holder.tvName = (TextView) vi.findViewById(R.id.nazwa_cwiczenia);
holder.tvName.setTypeface(tf ,1);
// holder.tvDescription = (TextView) vi.findViewById(R.id.textView_item_description);
vi.setTag(holder);
}
Since you pass in the context when calling the ListView constructor,
public ListviewAdapter(Context context, ArrayList<Cwiczenie> data) {
mLayoutInflater = LayoutInflater.from(context);
listaCwiczen = data;
}
Save the context into a variable? i.e.
// Allows you to use the context afterwards
private Context context = null;
public ListviewAdapter(Context context, ArrayList<Cwiczenie> data) {
this.context = context;
mLayoutInflater = LayoutInflater.from(context);
listaCwiczen = data;
}
And you can use it to get your assets.
Well, when you call "getContext()" ,it won't get the context of the activity you are in ,therefor, it won't work.What you want, is to get the context sent via the constructor and use it.
So, declare a context:
Private Context context;
Than ,in your constructor, go for this:
this.context = context;
This will practically get the context sent via the constructor and set it to your local variable.
Now you can use it like this:
context.getAssets()...//and so on
Related
I'm doing an app that uses BaseAdapter to see installed app in an Android device.
In this Listview there are more items, but in the adapter there are only two, and from the second (the package name) I get the other ones
I'm searching a way to sort the items of this adapter for an item that is in the listview, but not in the adapter. Here there is my code:
class AppsAdapter extends BaseAdapter{
private Context mContext;
private List<Pair<String, List<String>>> mAppsWithPermission;
AppsAdapter(Context context, List<Pair<String, List<String>>> appsWithPermission) {
mContext = context;
mAppsWithPermission = appsWithPermission;
}
static class ViewHolder {
TextView appName;
TextView appPermissions;
ImageView appIcon;
TextView Lines;
}
#Override
public int getCount() {
return mAppsWithPermission.size();
}
#Override
public Object getItem(int position) {
return mAppsWithPermission.get(position);
}
#Override
public long getItemId(int position) {
return mAppsWithPermission.get(position).hashCode();
}
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.appName = convertView.findViewById(R.id.list_item_appname);
holder.appPermissions = convertView.findViewById(R.id.list_item_apppermissions);
holder.appIcon = convertView.findViewById(R.id.list_item_appicon);
holder.Lines = convertView.findViewById(R.id.list_item_lines);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final Pair<String, List<String>> item = mAppsWithPermission.get(position);
final PackageManager packageManager = mContext.getPackageManager();
String mAppPer = item.second.toString();
int lineCount = holder.appPermissions.getLineCount();
Log.v("LINE_NUMBERS", lineCount+"");
String strI = Integer.toString(lineCount);
holder.Lines.setText(strI);
if (mAppPer.matches("")) {
holder.Lines.setText("0");
}
});
return convertView;
}
}
When you see "item.second" it's the package name.
As you can think, I'm trying to sort the entire adapter for the descendant value of holder.lines (so StrI).
This is a different question from the others that talks about sorting an adapter, because I want to sort the adapter for an external value.
If you need further informations, you've just to ask me.
I am creating a playlist with 2 lines of name and genre, how to I can delete it.
This is MainActivity :
String[] gene, sl;
...
adp = new Adapter(MainActivity.this, gene, sl);
lv.setAdapter(adp);
This is Adapter
public class Adapter extends ArrayAdapter<String> {
private final Activity context;
private final String[] gene;
private final String[] sl;
SharedPreferences preferences;
public Adapter(Activity context, String[] gene ,String[] sl) {
super(context, R.layout.activity_m , gene);
this.context = context;
this.gene = gene;
this.sl = sl;
}
private class ViewHolder{
TextView txtgene, txtsl;
}
#Override
public View getView(final int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = context.getLayoutInflater();
view = inflater.inflate(R.layout.activity_m, null, true);
holder = new ViewHolder();
holder.txtgene = (TextView) view.findViewById(R.id.txtgene);
holder.txtsl = (TextView) view.findViewById(R.id.txtsl);
view.setTag(holder);
}else{
holder = (ViewHolder) view.getTag();
}
if (gene[position] != null) {
holder.txtgene.setText(gene[position]);
}
holder.txtsl.setText(sl[position]);
return view;
}
}
How to remove an item when you know its exact position ?
Thank !
You are using the ArrayAdapter constructor that takes an array. This in turn will create an immutable List internal to the ArrayAdapter. So, you will not be able to modify your adapter going this route.
Instead, make a new ArrayList from your array and call the ArrayAdapter constructor that takes a List.
So, change the super call in your Adapter constructor to this:
super(context, R.layout.activity_m, new ArrayList<>(Arrays.asList(gene)));
And then, when you want to remove an item given it's position, do this:
adp.remove(getItem(position));
PS: You should consider refactoring your gene and sl arrays into a class and then use it as the type of your List.
I apologize in advance if this is a duplicate. I am still new to android development and tried looking for a resolution however could not find one that works.
I am creating a to-do app and getting this error in my adapter.
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String assignment.Model.getAssignment()' on a null object reference
at assignment.Adapter.getView(Adapter.java:39)
and the line of code that it is referencing to is
assignment.setText(modelItems[position].getAssignment());
I believe that the position that I am setting it as is what is causing the error but I'm not sure how to fix it.
Here's part of the rest of my code for reference:
MainActivity.Java - onActivityResult
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
String assignmentSentBack = data.getStringExtra("editAssignment");
Integer monthSentBack = data.getIntExtra("month", 0);
Integer daySentBack = data.getIntExtra("day", 0);
modelItems = new Model[100];
ArrayList<Model> modelArrayList = new ArrayList<>(Arrays.asList(modelItems));
modelArrayList.add(new Model(assignmentSentBack, (monthSentBack + 1) + "/" + daySentBack, 0));
lv = (ListView) findViewById(R.id.listAssignment);
ListAdapter adapter = new Adapter(this, modelItems);
lv.setAdapter(adapter);
}
Second Activity - onSendActivity (Button)
public void onSendAssignment (View view) {
EditText editAssignmentET = (EditText)
findViewById(R.id.editAssignment);
String editAssignment = String.valueOf(editAssignmentET.getText());
DatePicker datePickerDP = (DatePicker)
findViewById (R.id.datePicker);
Integer month = Integer.valueOf(datePickerDP.getMonth());
Integer day = Integer.valueOf(datePickerDP.getDayOfMonth());
Intent goingBack = new Intent();
goingBack.putExtra("editAssignment", editAssignment);
goingBack.putExtra ("month", month);
goingBack.putExtra("day", day);
setResult(RESULT_OK, goingBack);
finish();
}
Adapter
public class Adapter extends ArrayAdapter {
Model[] modelItems = null;
Context context;
public Adapter(Context context, Model[] resource) {
super(context, R.layout.row, resource);
this.context = context;
this.modelItems = resource;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
convertView = inflater.inflate(R.layout.row, parent, false);
TextView assignment = (TextView) convertView.findViewById(R.id.assignment);
TextView dueDate = (TextView) convertView.findViewById(R.id.dueDate);
CheckBox cb = (CheckBox) convertView.findViewById(R.id.checkBox);
assignment.setText(modelItems[position].getAssignment());
dueDate.setText(modelItems[position].getDueDate());
if (modelItems[position].getValue() == 1)
cb.setChecked(true);
else
cb.setChecked(false);
return convertView;
}
}
Model
public class Model {
String assignment;
String dueDate;
int value;
Model (String assignment, String dueDate, int value){
this.assignment = assignment;
this.dueDate = dueDate;
this.value = value;
}
public String getAssignment(){
return this.assignment;
}
public String getDueDate(){
return this.dueDate;
}
public int getValue(){
return this.value;
}
}
Any help is appreciated. Thank you.
you should try to wrap it in an inner Holder class and define the parameters in that class
public class Adapter extends ArrayAdapter {
Model[] modelItems = null;
Context context;
public Adapter(Context context, Model[] resource) {
super(context, R.layout.row, resource);
this.context = context;
this.modelItems = resource;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
if (convertView == null) {
holder = new ViewHolder();
convertView = vi.inflate(R.layout.list_layout, null);
// Find the child views.
holder.assignment= (TextView) convertView.findViewById(R.id.txt_name);
holder.dueDate= (Button) convertView.findViewById(R.id.btn_invite);
holder.cb= (Button) convertView.findViewById(R.id.btn_track);
convertView.setTag(holder);
//....
}
// Reuse existing row view
else {
holder = (ViewHolder)convertView.getTag();
}
return convertView;
}
class ViewHolder {
TextView assignment;
TextView dueDate;
CheckBox cb;
}
}
change
public class Adapter extends ArrayAdapter {
to
public class Adapter extends ArrayAdapter<Model> {
You have created model array of size 100 here:
modelItems = new Model[100];
So, 100 models are being created but all 100 indexes have null value.
Then you have created ArrayList using that array:
ArrayList<Model> modelArrayList = new ArrayList<>(Arrays.asList(modelItems));
So again your modelArrayList has 100 null objects. Which BTW you are using no where.
You are passing modelItems into constructor of Adapter. So now since all you items are null, you are getting this exception.
Try to do something like this:
ArrayList<Model> modelArrayList = new ArrayList<>();
modelArrayList.add(new Model(assignmentSentBack, (monthSentBack + 1) + "/" + daySentBack, 0));
Similarly add more model objects like that.
Pass this modelArrayList in your adapter's constructor and use this (instead of array) to display the list.
lv = (ListView) findViewById(R.id.listAssignment);
ListAdapter adapter = new Adapter(this, modelArrayList)
And thus your adapter will be like this:
ArrayList<Model> modelArrayList;
Context context;
public Adapter(Context context, ArrayList<Model> resource) {
super(context, R.layout.row, resource);
this.context = context;
this.modelArrayList = resource;
}
I'm trying to fetch the data stored using a custom CursorAdapter, but so far it is failing silently. It just loads a blank view and doesn't print anything.
Here is the onCreateView for the main fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.network_listview, container, false);
mListView = (ListView)view.findViewById(R.id.network_listview);
aToken = getSherlockActivity().getIntent().getStringExtra("token");
aTokenSecret = getSherlockActivity().getIntent().getStringExtra("token_secret");
context = getSherlockActivity().getBaseContext();
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.setOAuthConsumerKey(Const.CONSUMER_KEY);
builder.setOAuthConsumerSecret(Const.CONSUMER_SECRET);
builder.setOAuthAccessToken(aToken);
builder.setOAuthAccessTokenSecret((aTokenSecret));
Configuration configuration = builder.build();
mTwitter = new TwitterFactory(configuration).getInstance();
mListAdapter = getListAdapter();
mListView.setAdapter(mListAdapter);
updateList();
return view;
}
getListAdapter():
CursorAdapter getListAdapter() {
CursorAdapter ad = new TweetAdapter(getSherlockActivity(), null);
return ad;
}
TweetAdapter:
public class TweetAdapter extends CursorAdapter
{
private ImageLoader imageLoader;
private static class ViewHolder
{
private ImageView profileView;
private TextView updated;
private ImageView favoriteIcon;
private TextView name;
private TextView message;
private TextView retweeted_by;
private ViewHolder(View row)
{
profileView = (ImageView)row.findViewById(R.id.preview);
updated = (TextView)row.findViewById(R.id.updated);
favoriteIcon = (ImageView)row.findViewById(R.id.favorite_icon);
name = (TextView)row.findViewById(R.id.name);
message = (TextView)row.findViewById(R.id.message);
retweeted_by = (TextView)row.findViewById(R.id.retweeted_by);
}
}
public TweetAdapter(Context context, Cursor c){
super(context, c, true);
}
#Override
public void bindView(View row, Context context, Cursor cursor)
{
// this doesnt print out anything, even though there is data in the database
String tweetText = cursor.getString(cursor.getColumnIndex(Tweets.COL_TEXT_PLAIN));
System.out.println("Tweet Text: " + tweetText);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater) parent.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.item_tweet, parent, false);
ViewHolder viewHolder = new ViewHolder(row);
row.setTag(viewHolder);
return row;
}
}
updateList():
void updateList()
{
mCursor = getCursor();
Cursor oldCursor = mListAdapter.swapCursor(mCursor);
mListAdapter.notifyDataSetChanged();
if (oldCursor != null) {
oldCursor.close();
}
}
You pass a null Cursor when constructing the TweetAdapter instance, so your adapter starts out with no data. Then updateList() replaces the adapter's null Cursor with whatever is in mCursor (which you do not show in the code you provided).
If mCursor is also null, then your code will end up either displaying no content (which is what you are seeing) or throwing an uncaught exception.
So, make sure you actually do a query that fills in the mCursor variable before calling updateList() .
Can someone tell me how should am i going to create my listview which look similar [here][1].
Problem: How am i going to fulfill the sort of look and feel in my codes which has an icons, file name, and file size yet at the same time looking clean and simple on each file object as shown in the example in the link [here][2]??
Can someone guide on this matter because i'm rather new in android/java... Thanks
Refer to following url for how to implement custom listview
Update
public static class VideoInfo {
public String name = "";
public String size= "";
public String path = "";//add any more variables of which you want info
}
then where you are creating arraylist i.e getVideoFiles() create object of this class
Declare ArrayList<VideoInfo> videoItems;
private void getVideoFiles(File[] videoList)
{
videoItems = new ArrayList<VideoInfo>();
for (int i = 0; i < videolist.length; i++)
{
File mfile = videoList[i];
String path = mfile.getPath();
path = path.substring(path.lastIndexOf("/", path.indexOf("."));
VideoInfo model = new VideoInfo();
model.name = path;
model.size = mfile.length();
videoItems.add(model);
}
setListAdapter(new ListViewAdapter(this, R.layout.row, videoItems));
}
now in your adapter pass this object of arraylist and how you set variables in listview is already given in link above
Problem 2: And why is my listview
having error when the directory is
empty despite having this to handle
the "empty" in my xml
did you remember to name your listview?:
#id/android:list
And if you could for further helper PLEASE clear up problem 1, so its more clear and concise what you want.
UPDATE
The ID of the listview should be: #id/android:list
The ID of the texview should be: #id/android:empty
You haven't create custom adapter to incorporate the layout into codes listview.
Here is something you can use
private class ListViewAdapter extends ArrayAdapter<Object> {
private ArrayList<Object> items;
public ListViewAdapter(Context context, int textViewResourceId,
ArrayList<Object> items) {
super(context, textViewResourceId, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
Object info = items.get(position);
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
if (info != null) {
ImageView imView = (ImageView) v.findViewById(R.id.icon);
TextView txtname =(TextView) v.findViewById(R.id.toptext);
TextView txtAddr = (TextView) v.findViewById(R.id.bottomtext);
//set image and set text as you like
}
return v;
}
}
Hope this can help.
First Create the Layout that you want to display for each row in your list then Extend the BaseAdapter class to Customize your Lists. This class contains getView method to replicate the rows in your lists as many times as you want to.
class HighScoreAdapter extends BaseAdapter
{
/* layout inflater to convert your XML layout to View to be rendered in your Each row of Lists.*/
private LayoutInflater minflator = LayoutInflater.from(HighScoreList.this);
ViewHolder holder;
#Override
public Object getItem(int position)
{
return position;
}
#Override
public long getItemId(int position)
{
return position;
}
boolean toRemove = false;
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
/* first time is null */
if (convertView == null )
{
convertView = minflator.inflate(R.layout.highscorelist, null);
holder = new ViewHolder();
holder.rank = (TextView) convertView.findViewById(R.id.user_id);
holder.username = (EditText) convertView.findViewById(R.id.user_nameedit);
holder.time = (TextView) convertView.findViewById(R.id.user_time);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.rank.setText(String.valueOf(position+1)+".");
/* returns the view for next row as layout will be same i.e. this increases the your list's scrolling and working faster even though your list contains thousands of Entry*/
return convertView;
}
/* this class is to make reference to your child views of your layout by using this you can set your child views properties and Listeners acording to your need.*/
class ViewHolder
{
TextView rank;
EditText username;
TextView time;
}
}
I hope this solves your problem completely.. :)
Add this method to your code and if you get any error or Exception please let me know.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
Object info = items.get(position);
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
if (info != null) {
ImageView imView = (ImageView) v.findViewById(R.id.icon);
TextView txtname =(TextView) v.findViewById(R.id.toptext);
TextView txtAddr = (TextView) v.findViewById(R.id.bottomtext);
//set image and set text as you like
imview.setImageBitmap(IMAGE YOU WANT TO SET AAS ICON);
txtname.setText(FILENAME YOU WANT TO SET);
txtadr,setText(FILESIZE YOU WANT TO SET);
// Better you take each info filename,filesize and icon in a arraylist and set them
}
return v;
}