Losing Reference to Assigned View - android

So I am extending the ListPreference in order to achieve the effect I need.
I would like to have a titleView, a messageView, and then the listView in my dialog.
I override the onCreateDialogView() method in order to do this and am able to display the messageView successfully by creating a textview and adding it to the view with this code:
#Override
protected View onCreateDialogView() {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ListView lv = (ListView) inflater.inflate(R.layout.dialog_layout, null);
_messageView= (TextView) inflater.inflate(R.layout.dialog_header, null);
_messageView.setText("Hello World");
lv.addHeaderView(_messageView);
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(getContext(), R.layout.dialog_list_choice, getEntries());
lv.setAdapter(adapter);
return lv;
}
Now when I assign the created TextView the variable _messageView and set the text it works fine.
However, when I click the preference, I want the dialog's messageView text to change.
I do so with the following code:
public void showWithCode(String code){
if (_messageView != null) {
_messageView.setText(code);
}
showDialog(null);
}
The Dialog displays, however _messageView is always null so I cannot have my message reflect my actions!
So my question is, how is it that I assigned it earlier yet it is null when I need it?

Related

Dynamic view setting same value for every view added dynamically

With following function, I am adding view dynamically. but through this, last call values to "addview" are getting set in all views. Like If i call addview function with "aaaa" in its 0 index it will add one view with aaaa name, and then again i call addview with "bbbb" in its 0 index it will add one more view but this time it set "bbbb" to previous view also. Means now both dynamically added view will have "bbbb" value in its edittext. Please help.
public void addView(String[] values) {
layoutInflater =
(LayoutInflater) getActivity( ).getBaseContext( ).getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View convertView = layoutInflater.inflate(R.layout.lay_fcp_child, null);
ImageView ivRemove;
EditText etName;
RelativeLayout layDOB;
final TextView tvDate;
final Spinner spRelationship;
tvDate = (TextView) convertView.findViewById(R.id.tv_ins_dob);
layDOB = (RelativeLayout) convertView.findViewById(R.id.lay_ins_dob);
etName = (EditText) convertView.findViewById(R.id.et_ins_personname);
etName.setFilters(new InputFilter[]{filterName, new InputFilter.LengthFilter(60)});
ivRemove = (ImageView) convertView.findViewById(R.id.iv_fcp_remove);
spRelationship = (Spinner) convertView.findViewById(R.id.sp_fcp_relationship);
AdapterIDValue adapterRelations = new AdapterIDValue(getActivity(), R.layout.spinner_selected_item_relation, alSRelationship);
spRelationship.setAdapter(new NothingSelectedSpinnerAdapter(adapterRelations, R.layout.spinner_hint_relationship, getActivity()));
etName.setText(values[0]);
spRelationship.setSelection(Integer.parseInt(values[3]));
tvDate.setText(values[1]);
tvDate.setTag(values[2]);
tvDate.setTextColor(Color.BLACK);
try {
layDynamic.addView(convertView);
}catch (Exception sdf){
System.err.print(sdf);
}
svMain.fullScroll(ScrollView.FOCUS_DOWN);
}
Yes you can create with RecyclerView OR ListView, or if you want to do with scroll view the generate dynamic Ids of every view, so you can solve your problem.
Each call to addview(...) method will create a new adapter and set it to spRelationship. This new adapter replace the previous. You are not "adding views", you're "setting the views".
You have to set the adapter only once and change its data.

Set visibility for an image within a ListView row

Overview:
I have a ListView with a custom adapter/layout, every time a user adds a new row (which contains a number), I check if that number is the smallest in the list. If so, an image within that row must be set as visible while setting all other row's images as invisible.
Problem:
My ListView does not set any row's image as visible, even though I have the index of the smallest element.
How I'm doing it:
//In MainActivity
private void addProduct(float price) { //User adds product
priceList.add(price); //Add to Float list
adapter.notifyDataSetChanged();
updateView(findMinIndex(priceList)); //Find smallest val indx
}
private void updateView(int index){
View v = listView.getChildAt(index -
listView.getFirstVisiblePosition());
if(v == null)
return;
ImageView checkMark = (ImageView) v.findViewById(R.id.check_mark);
checkMark.setVisibility(View.VISIBLE); //Initially set Invisible
}
Edit, CustomAdapter:
public CustomList(Activity context,
ArrayList<Float> priceList) {
super(context, R.layout.list_single, priceList);
this.context = context;
priceList = priceList;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.list_single, null, true);
TextView price = (TextView) rowView.findViewById(R.id.new_price);
ImageView cheapest = (ImageView) rowView.findViewById(R.id.check_mark);
price.setText(priceList.get(position) + "");
return rowView;
}
Thank you
It is your priceList binded with the adapter?
First of all i would put a breakpoint to see if you are getting the right view in the updateView method.
try this way;
Create a Pojo class with imageview and it's state(Visibility) initially set all to invisible
Add your items to the ArrayList of Pojo Class type.
when user enters a new row based on your requirement set visibility state to true or false(visible or invisible) and call notifyDataSetChanged() to the adapter.
Doing this way you can have a easy track of the items.
I got it working :).
Problem is that adapter.notifyDataSetChanged(); is async, so while it's doing that, updateView(findMinIndex(priceList)); runs but doesn't find the new row as it should. Therefore, I add a runnable to the ListView object as so:
adapter.notifyDataSetChanged();
listView.post( new Runnable() {
#Override
public void run() {
updateView(findMinIdx(priceList));
}
});
Now it works perfectly!

Changing the visibility of a image inside a list view

I have this function in the bottom, In this function I fill the listview in the MainActivity, I can fill with any text I want, but I do not know how to hide, I tried the thing in the comment part to hide it, but did not work.
I need to check a certain condition and if true hide R.id.dire_win, if false hide R.id.radiant_win
Also I need to fill R.id.team01_pic in each row of the list view with an .png/.jpg url.
Thanks for your help in advance.
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
SingleContactActivity.this, matchList,
R.layout.list_match, new String[] { TAG_team01_name, TAG_team02_name , TAG_RESULT }, new int[] {
R.id.team01_name, R.id.team02_name , R.id.result});
//ImageView imgView = (ImageView) findViewById(R.id.radiant_win);
//imgView.setVisibility(View.INVISIBLE);
//TextView textview =(TextView )findViewById(R.id.text);
setListAdapter(adapter);
}
Update: I tried to create this function as one of the answers said, but did not work .
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View rowView = inflater.inflate(R.layout.list_match, parent, false);
//TextView textView = (TextView) rowView.findViewById(R.id.label);
ImageView imageView = (ImageView) rowView.findViewById(R.id.radiant_win);
//textView.setText(values[position]);
// change the icon for Windows and iPhone
//String s = values[position];
imageView.setImageResource(R.drawable.team_navi);
//imageView.setVisibility(View.INVISIBLE);
return rowView;
}
Solution is to use Custom adapter instead of Simple adapter. Then you have to create a custom xml with all widgets you want (imageView,TextField, etc.). In your custom adapter class, inside the getView() method, that you have previously overridden, you can specify the conditions of imageView visibility. This example should help you:
http://www.learn-android-easily.com/2013/06/listview-with-custom-adapter.html
Also read this (http://developer.android.com/reference/android/widget/Adapter.html)

Trying to setOnClickListener for TextView not in main layout

I have a TextView that I am turning into a button. The TextView actually lives on a secondary layout.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.history);
this is the main layout here "R.layout.history"
That loads a bunch of results in a ListAdapter and each result is displayed using R.layout.card_background
I am trying to initialize and set the setOnClickListener for a TextView located on R.Layout.card_background but I am getting a nullPointerException.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.history);
Typeface tf = Typeface.createFromAsset(getAssets(),"Roboto-Light.ttf");
ListView listContent = (ListView) findViewById(android.R.id.list);
TextView history = (TextView) findViewById(R.id.history);
history.setTypeface(tf);
Cursor cursor = db.getAllLogs();
Log.d("history.java", "finished Cursor cursor = db.getAllLogs();");
String[] from = {"_id", "dd", "gg", "ppg", "odo"};
int[] to = {deleteVal, R.id.cardDate, R.id.cardG, R.id.cardP, R.id.cardM};
ListAdapter adapter = new SimpleCursorAdapter(this, R.layout.card_background, cursor, from, to);
listContent.setAdapter(adapter);
TextView cardDelete = (TextView) findViewById(R.id.cardDelete);
cardDelete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v){
}
});
}
Any idea how I can set that and stop getting the NPE?
Thanks
You'll have to write a custom Adapter that extends SimpleCursorAdapter and add the OnClickListener in the getView() method.
As you try it now, the TextView is searched in the activity layout, not found of course, thus the variable does not get filled, and the app crashes as soon as you want to perform a method on a null pointer.
i believe that your activity is bind to another contentView which is setContentView(R.layout.history);hence the nullPointerException.
So I actually did a little more digging and tried this. If someone can tell me why this is a bad/good idea though I would appreciate it as I'd rather not commit it to memory if it is going to be harmful to the application.
final LayoutInflater cardLayout = getLayoutInflater();
final View cardDeleteText = cardLayout.inflate(R.layout.card_background, null);
TextView cardDelete = (TextView) cardDeleteText.findViewById(R.id.cardDelete);
cardDelete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v){
}
});
you can inflate a custom layout from card_background
use this code
View card_background_view = inflater.inflate(R.layout.card_background, container, false);
then
replace this
TextView history = (TextView) findViewById(R.id.history);
with this
TextView history =(TextView)card_background_view.findViewById(R.id.history);

How to get elements(findViewById) for a layout which is dynamically loaded(setView) in a dialog?

I need to get the EditText that's defined in an xml layout which is dynamically loaded as a view in a preference dialog i.e. :
public class ReportBugPreference extends EditTextPreference {
#Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
builder.setView(LayoutInflater.from(ctx).inflate(R.layout.preference_report_bug_layout,null));
EditText edttxtBugDesc = (EditText) findViewById(R.id.bug_description_edittext); // NOT WORKING
}
}
EDIT : SOLUTION by jjnFord
#Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
View viewBugReport = LayoutInflater.from(ctx).inflate(R.layout.preference_report_bug,null);
EditText edttxtBugDesc = (EditText) viewBugReport.findViewById(R.id.bug_description_edittext);
builder.setView(viewBugReport);
}
Since you are extending EditTextPreference you can just use the getEditText() method to grab the default text view. However, since you are setting your own layout this probably won't do what you are looking for.
In your case you should Inflate your XML layout into a View object, then find the editText in the view - then you can pass your view to the builder. Haven't tried this, but just looking at your code I would think this is possible.
Something like this:
View view = (View) LayoutInflater.from(ctx).inflate(R.layout.preference_report_bug_layout, null);
EditText editText = view.findViewById(R.id.bug_description_edittext);
builder.setView(view);
LayoutInflater is needed to create (or fill) View based on XML file in
runtime. For example if you need to generate views dynamically for
your ListView items.
What is the layout inflater in an Android application?
Create your LayoutInflater:
LayoutInflater inflater = getActivity().getLayoutInflater();
Create your view by inflater refered to your_xml_file:
View view= inflater.inflate(R.layout.your_xml_file, null);
Find your object in your layout by id.
TextView textView =
(TextView)view.findViewById(R.id.text_view_id_in_your_xml_file);
Use your object: i.e.
textView.setText("Hello!");

Categories

Resources