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.
Related
I have created a dynamic view which repeats for a specific times. The view has 2 textViews and 2 radio buttons with default values. I want to change the Text values from program but getting nullpointer exception, Here is my code:
LayoutInflater inflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout scrollViewLinearlayout = (LinearLayout)findViewById(R.id.parent); // The layout inside scroll view
//int count=50;
for(int i = 0; i < Studentlist.length; i++){
String data = Studentlist[i];
String RollNum = data.split("--")[0];
String Name = data.split("--")[1];
LinearLayout layout2 = new LinearLayout(context);
layout2.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
View item = inflater.inflate(R.layout.item_layout, null, false);
layout2.addView(item);
layout2.setId(i);
TextView trollnum = (TextView)findViewById(R.id.RollNum);
trollnum.setText(RollNum);
TextView tname = (TextView)findViewById(R.id.Name);
tname.setText(Name);
scrollViewLinearlayout.addView(layout2);
Log.d("Id is: ", trollnum.getText().toString());
I am getting nullpointer at 'trollnum.setText(RollNum);'
How do i change the text in the View?
You are trying to find the view in the activity's layout where it doesn't exist instead of finding it in the layout you just inflated.
Replace
TextView trollnum = (TextView)findViewById(R.id.RollNum);
TextView tname = (TextView)findViewById(R.id.Name);
With
TextView trollnum = (TextView) item.findViewById(R.id.RollNum);
TextView tname = (TextView) item.findViewById(R.id.Name);
I am trying to add an xml layout programmatically. It is giving error at time.setText(timeFormat); When I remove this line I get the default text value of TextView. Also I have checked that timeFormat is not null. Why am I getting this error?
Here's my code:
In onCreate(),
new GetContacts().execute();
addPost(timeFormat,message);
addPost() function:
public void addPost(String timef,String postmessage){
LayoutInflater i = getLayoutInflater();
View v = i.inflate(R.layout.list_item, null);
TextView time = (TextView)findViewById(R.id.time);
Log.d("TIME HAS COME", timeFormat);
time.setText(timeFormat);
TextView message1 = (TextView)findViewById(R.id.message);
message1.setText(message);
LinearLayout ll = (LinearLayout)findViewById(R.id.feedsLayout);
ll.addView(v);
}
I have watched Android developer's videos on animating ListView insertion and deletion on YouTube. These have had very complex code in them and I tried searching for something else and found this.
http://karnshah8890.blogspot.fi/2013/04/listview-animation-tutorial.html
It has pretty simple implementation that works in most parts. My problem is that when I insert a new item in the ArrayList that is supplied to the ArrayAdapter, all the existing elements get reinserted due to adapter.notifyDataSetChanged()... I think. When I insert an entry in the ListView, how do I prevent all the entries from getting animated again? I just want the new one to animate in.
I use my ListView in the code this way:
toggles = (ListView) v.findViewById(R.id.toggleListView);
adapter = new ToggleListAdapter(getActivity(), toggleTasks);
toggles.setAdapter(adapter);
When a new item is inserted, I update the ArrayList (toggleTasks) and then call notifyDataSetChanged() on the adapter.
toggleTasks.add(task);
adapter.notifyDataSetChanged();
Here is my getView() method from the ArrayAdapter.
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ToggleTask task = toggles.get(position);
String startActionName = "";
String finishActionName = "";
int imageDrawableId = -1;
// Deleted the part where I get the values for those three variables above
final Holder holder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.mute_toggles_toggle_view, null);
holder = new Holder();
holder.image = (ImageView) convertView.findViewById(R.id.image);
holder.startAction = (TextView) convertView.findViewById(R.id.startAction);
holder.finishAction = (TextView) convertView.findViewById(R.id.finishAction);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.image.setImageResource(imageDrawableId);
holder.startAction.setText(startActionName);
holder.finishAction.setText(finishActionName);
Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.listview_push_left_in); // Third animation example on the site linked earlier
animation.setDuration(500);
convertView.startAnimation(animation);
animation = null;
return convertView;
}
in the ArrayAdatper class add a global integer (I'll call it changedIndex) and create getter and setters for it. Then before you add an item to the list say adapter.setChangedIndex(index) (whatever you name your setter). You are essentially telling it ahead of time which one you want to animate.
Change this in getView
if(changedIndex == position){
Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.listview_push_left_in); // Third animation example on the site linked earlier
animation.setDuration(500);
convertView.startAnimation(animation);
animation = null;
}
then change
toggleTasks.add(task);
adapter.notifyDataSetChanged();
to
toggleTasks.add(task);
toggles.getPosition(task);
adapter.notifyDataSetChanged();
*I haven't checked any of this code but I believe it should work
Well if you want to animate only the last item inserted, then before animating check if it is last item in the List.
if (position == getCount() - 1) {
Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.listview_push_left_in); // Third animation example on the site linked earlier
animation.setDuration(500);
convertView.startAnimation(animation);
animation = null;
}
Use the ListViewAnimations library. After setting up your ListView and ListAdapter like this:
MyListAdapter mAdapter = new MyListAdapter(this, getItems());
SwingRightInAnimationAdapter swingRightInAnimationAdapter = new SwingRightInAnimationAdapter(mAdapter);
// Assign the ListView to the AnimationAdapter and vice versa
swingRightInAnimationAdapter.setAbsListView(getListView());
getListView().setAdapter(swingRightInAnimationAdapter);
Call AnimationAdapter.setShouldAnimateFromPosition(int position) somewhat like this:
swingRightInAnimationAdapter.setShouldAnimateFromPosition(swingRightInAnimationAdapter.getCount());
swingRightInAnimationAdapter.add(myItem);
Have a look at the wiki for more information about how to use the library.
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);
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)