When my fragment is created it calls
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View layout=inflater.inflate(R.layout.fragment_item_fragment1, container, false);
populatePage();
return layout;
}
and within that calls the populatepage() method. Within that method a call to a webservice is made. I have verified that the data exits and everything runs without error.
public void populatePage(){
String globalKey = "key";
String url = "";
//shared preferences
SharedPreferences settings = getActivity().getSharedPreferences(sharedPreferences, 0);
final String SESSION_KEY = settings.getString("SESSION_KEY", "nothing is here");
String FILE_KEY = settings.getString("FILE_KEY", "");
String page = settings.getString("PAGE", "Part");
final String group = settings.getString("FRAG_1", "");
String record = settings.getString("RECORD", "");
//BUILD THE URL WE NEED
url = "https://url.com/"
//loading page
//Declare the headers and add the pairs
Headers header = new Headers();
header.add("X-SESSION-KEY", SESSION_KEY);
header.add("X-GLOBAL-KEY", globalKey);
//Layout for building upon
final LinearLayout ll = new LinearLayout(getActivity());
ll.setOrientation(LinearLayout.VERTICAL);
$.ajax(new AjaxOptions().url(url)
.type("GET")
.dataType("json")
.headers(header)
.contentType("application/json")
.context(getActivity()).success(new Function() {
#Override
public void invoke($ droidQuery, Object... params) {
JSONObject json = (JSONObject) params[0];
try {
Boolean session = json.getBoolean("valid");
if (session) {
JSONArray recordsArray = json.getJSONArray("field");
String groupName = ""; //we compare group to this before adding it as a preference since we dont want dupes
for (int i = 0; i < recordsArray.length(); i++) {
JSONObject record = recordsArray.getJSONObject(i);
//BIG MESSY IF STATEMENT TO PARSE DATA! HOORAY!
if (record.getString("group").equals(group)) {
if (record.getString("valueType").equals("Text")) {
TextView label = new TextView(getActivity());
label.setText(record.getString("label"));
label.setPadding(20, 20, 20, 0);
label.setTextSize(20);
label.setTypeface(null, Typeface.BOLD);
label.setTextColor(Color.BLACK);
ll.addView(label);
TextView value = new TextView(getActivity());
value.setPadding(20, 0, 20, 20);
value.setTextSize(17);
value.setTextColor(Color.BLACK);
value.setText(record.getString("value"));
ll.addView(value);
} else if (record.getString("valueType").equals("Image")) {
TextView label = new TextView(getActivity());
label.setText(record.getString("label"));
label.setPadding(20, 20, 20, 20);
label.setTextSize(20);
label.setTypeface(null, Typeface.BOLD);
label.setTextColor(Color.BLACK);
ll.addView(label);
byte[] decodedString = Base64.decode(record.getString("value"), Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
ImageView image = new ImageView(getActivity());
image.setImageBitmap(decodedByte);
image.setScaleType(ImageView.ScaleType.FIT_START);
}
}
}
progressDialog.dismiss();
progressDialog.cancel();
} else {
droidQuery.toast("Session Expired", Toast.LENGTH_LONG);
Intent intent = new Intent(getActivity(), LoginActivity.class);
startActivity(intent);
}
} catch (JSONException e) {
droidQuery.toast(e.toString(), Toast.LENGTH_SHORT);
}
}
}
).
error(new Function() {
#Override
public void invoke($ droidQuery, Object... params) {
Log.e("$", "broke good");
//DELETE THIS
Context context = getActivity();
CharSequence text = "Could not connect to Server";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
}
));
}
}
For some reason when the app launches the fragment is blank as if nothing is added and I can't figure out why. I've tried added the linearlayout to the fragments xml and grabbing it by it's ID but I get a null reference error even though I do just that in another fragment elsewhere in the program and it works.
It looks like you're correctly adding the view to the Linear Layout you've created, but I don't see a spot where you're adding that newly created Layout to the Fragment's View.
Here is the documentation and an example
Taken from the example:
LayoutInflater vi = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.your_layout, null);
// fill in any details dynamically here
TextView textView = (TextView) v.findViewById(R.id.a_text_view);
textView.setText("your text");
// insert into main view
ViewGroup insertPoint = (ViewGroup) findViewById(R.id.insert_point);
insertPoint.addView(v, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
Modified to your specific situation:
populatePage(layout);
public void populatePage(View v){
...other code here...
RelativeLayout relativeLayout = (RelativeLayout)v. findViewById(R.id.id_that_exists_in_your_xml);
relativeLayout.addView(ll, 0, new ViewGroup.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT));
}
You're right, regarding your most recent edit, I made a mistake. Get reference to the base layout object in your XML file (Relative/Linear/Frame layout etc), and then call the addView method on that.
From the example you gave the ll object just created but never added to fragment. You can return LinearLayout object from populatePage() function and add it to fragment view in onCreateView.
Related
In my main activity I display a ListView which uses a custom BaseAdapter (ThoughtListAdapter).
listView = (ListView) findViewById(R.id.list);
adapter = new ThoughtListAdapter(this, resultingThoughts);
listView.setAdapter(adapter);
Every item in the ListView has a custom layout containing a TextView and two Button.
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_item_thought, null);
}
thoughtText = (TextView) convertView.findViewById(R.id.thought_text_view);
likeButton = (Button) convertView.findViewById(R.id.thought_like_button);
dislikeButton = (Button) convertView.findViewById(R.id.thought_dislike_button);
When a Button is clicked an AsyncTask (AsyncPost) is called which connects to my database and makes some changes.
likeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
System.out.println("LIKE CLICKED");
Thought t = thoughtItems.get(position);
thoughtId = t.getId();
opinion = 1;
AsyncPost asyncPost = new AsyncPost(activity,ThoughtListAdapter.this);
asyncPost.execute(SHARE_THOUGHT_URL,
TAG_PERSON_EMAIL, "m#b.it",
TAG_THOUGHT_ID, thoughtId.toString(),
TAG_OPINION, opinion.toString());
}
});
What I need is making both Button-s of a list item disappear after the AsyncTask is done with a successful outcome. I have a method onComplete(JSONObject json) which elaborates the JSONObject returned by the AsyncTask. I try to make the buttons non visible inside the onComplete method, but this doesn't work because onComplete() doesn't know which exact button has been clicked.
How can I pass an instance of the exact clicked button inside onComplete() and make disappear only the Like and Dislike buttons of the concerned list item?
AsyncPost is a global AsyncTask used by all my other activities. I would strongly prefer to leave it alone. The onComplete() method functions as the onPostExecute() method of the AsyncTask.
Here are the getView() and onComplete() methods inside my BaseAdapter, which contain all the code shown above.
Thank you.
public View getView(final int position, View convertView, ViewGroup parent) {
if (layoutInflater == null) {
layoutInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_item_thought, null);
}
thoughtText = (TextView) convertView.findViewById(R.id.thought_text_view);
likeButton = (Button) convertView.findViewById(R.id.thought_like_button);
dislikeButton = (Button) convertView.findViewById(R.id.thought_dislike_button);
//thoughtItems is a list of custom ojbects (Thought)
Thought t = thoughtItems.get(position);
//Here i set the content of the current TextView
thoughtText.setText(t.getText());
//the two buttons do basically the same thing when get clicked
likeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Thought t = thoughtItems.get(position);
thoughtId = t.getId();
opinion = 1;
AsyncPost asyncPost = new AsyncPost(activity,ThoughtListAdapter.this);
asyncPost.execute(SHARE_THOUGHT_URL,
TAG_PERSON_EMAIL, "m#b.it",
TAG_THOUGHT_ID, thoughtId.toString(),
TAG_OPINION, opinion.toString());
}
});
dislikeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Thought t = thoughtItems.get(position);
thoughtId = t.getId();
opinion = 0;
AsyncPost asyncPost = new AsyncPost(activity,ThoughtListAdapter.this);
asyncPost.execute(SHARE_THOUGHT_URL,
TAG_PERSON_EMAIL, "m#b.it",
TAG_THOUGHT_ID, thoughtId.toString(),
TAG_OPINION, opinion.toString());
}
});
return convertView;
}
#Override
public void onComplete(JSONObject json) {
if (json != null) {
try {
if (json.getInt(TAG_SUCCESS) == 0) {
Toast.makeText(activity, "Operazione non riuscita.", Toast.LENGTH_LONG).show();
} else {
//if everything is good i try to make the buttons of that particular list item disappear
likeButton.setVisibility(View.GONE);
dislikeButton.setVisibility(View.GONE);
}
}
catch (JSONException e) {
Log.e(TAG_LOG, "JSONException", e);
}
}
else Toast.makeText(activity, "Errore connessione!", Toast.LENGTH_LONG).show();
}
One solution to this would be to have something on your Thought object to indicate whether or not to show the buttons.
So in your getView() method you check this
likeButton = (Button) convertView.findViewById(R.id.thought_like_button);
dislikeButton = (Button) convertView.findViewById(R.id.thought_dislike_button);
Thought t = thoughtItems.get(position);
if (t.hideButtons()) {
likeButton.setVisibility(View.GONE);
dislikeButton.setVisibility(View.GONE);
}
else {
likeButton.setVisibility(View.VISIBLE);
dislikeButton.setVisibility(View.VISIBLE);
}
Then you would need to have your onComplete method return the id of the Thought object that it related to. Then inside your onComplete you could do
int id = //get your id from your JSON response
for(Thought t : thoughtItems) {
if (t.getId() == id) {
t.setHideButtons(true);
notifyDataSetChanged();
break;
}
}
By calling notifyDataSetChanged() it will redraw your list and when it does the check for whether it should show the buttons or not it will not show them because it was set on that thought item
I've searched all the posts I can find, and none seem to help with my situation. I have an android project that uses web services to pull down hourly weather data and populate a listView with the results.
The weird problem I'm having is that when I debug the project on my android phone, the main activity is blank and the listView isn't populated. If I run the project from android studio with my phone locked, and then unlock my phone the app opens on my phone with all of the listView properly formatted and populated.
I feel like it's a race condition issue between the asynctask and the adapter, but I can't seem to resolve it. I tried making my asyncTask an inner private class and calling notifyDataSetChanged on the adapter inside the onPostExecute method, but to no avail. I feel it must be something simple, but I'm relatively new to Android dev, so I'm stuck.
I have three classes that I'll post the pertinent code from
MainActivity.java (onCreate)
public class MainActivity extends ActionBarActivity {
ArrayList<Weather> w = new ArrayList<Weather>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadWeatherTask myTask = new DownloadWeatherTask(w);
WeatherAdapter myAdapter = new WeatherAdapter(this,w);
ListView l = (ListView) findViewById(R.id.weatherList);
l.setAdapter(myAdapter);
myTask.execute();
}
}
WeatherAdapter.java
public class WeatherAdapter extends ArrayAdapter<Weather>{
public WeatherAdapter(Context context, ArrayList<Weather> weather) {
super(context, R.layout.item_weather, weather);
}
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Weather forecast = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_weather, parent, false);
}
// Lookup view for data population
TextView tvTime = (TextView) convertView.findViewById(R.id.listTime);
TextView tvDescr = (TextView) convertView.findViewById(R.id.listDescr);
TextView tvTemp = (TextView) convertView.findViewById(R.id.listTemp);
TextView tvHumid = (TextView) convertView.findViewById(R.id.listHumid);
ImageView ivWeather = (ImageView) convertView.findViewById(R.id.weatherImg);
// Populate the data into the template view using the data object
tvTime.setText(forecast.time);
tvDescr.setText(forecast.description);
tvTemp.setText(forecast.temperature+"°(F)");
tvHumid.setText(forecast.humidity+"% humidity");
ivWeather.setImageBitmap(forecast.weatherImg);
// Return the completed view to render on screen
return convertView;
}
}
DownloadWeatherTask.java
public class DownloadWeatherTask extends AsyncTask<Void,Void,Void>{
ArrayList<Weather> data;
public DownloadWeatherTask(ArrayList<Weather> a){
data = a;
}
public ArrayList<Weather> getData() {
return data;
}
protected Void doInBackground(Void...params) {
try {
String website = "http://api.wunderground.com/api/1111111111111/geolookup/q/autoip.json";
URL site = new URL(website);
HttpURLConnection weatherUnderground = (HttpURLConnection) site.openConnection();
weatherUnderground.connect();
JsonParser weatherParser = new com.google.gson.JsonParser();
JsonElement weatherJson = weatherParser.parse(new InputStreamReader((InputStream) weatherUnderground.getContent()));
JsonObject weatherObj = weatherJson.getAsJsonObject();
String zip = weatherObj.get("location").getAsJsonObject().get("zip").getAsString();
String city = weatherObj.get("location").getAsJsonObject().get("city").getAsString();
String state = weatherObj.get("location").getAsJsonObject().get("state").getAsString();
String hourly = "http://api.wunderground.com/api/111111111111/hourly/q/" + state + "/" + city + ".json";
URL hourlySite = new URL(hourly);
HttpURLConnection hourlyConnection = (HttpURLConnection) hourlySite.openConnection();
hourlyConnection.connect();
com.google.gson.JsonParser hourlyParser = new com.google.gson.JsonParser();
JsonElement hourlyWeatherJson = weatherParser.parse(new InputStreamReader((InputStream) hourlyConnection.getContent()));
JsonArray weatherArr = hourlyWeatherJson.getAsJsonObject().get("hourly_forecast").getAsJsonArray();
int l = weatherArr.size();
for (int i = 0; i < l; i++) {
String date = weatherArr.get(i).getAsJsonObject().get("FCTTIME").getAsJsonObject().get("pretty").getAsString();
String temp = weatherArr.get(i).getAsJsonObject().get("temp").getAsJsonObject().get("english").getAsString();
String condition = weatherArr.get(i).getAsJsonObject().get("condition").getAsString();
String humidity = weatherArr.get(i).getAsJsonObject().get("humidity").getAsString();
String iconUrl = weatherArr.get(i).getAsJsonObject().get("icon_url").getAsString();
Bitmap icon = getBitmapFromURL(iconUrl);
data.add(new Weather(date, condition, temp, humidity, icon));
}
} catch (IOException e) {
Log.e("Error: ",e.toString());
}
return null;
}
protected void onPostExecute(Void...params){
}
}
Below are links to my screenshots showing the app not populating the listView, and the app working properly when the program is run while the phone is initially locked.
Any help would be greatly appreciated!!
Thanks
In postExecute(), you need to update the adapter's List and then invoke its notifyDataSetChanged method. I suspect that you were forgetting to update the adapter's data.
The other option is to create a new adapter with the new data, and set the new adapter on the ListView.
I figured out what the issue was! I hadn't added #Override to my onPostExecute() method so it was never being called.
I added the notifyDataSetChanged to my onPostExecute as suggested, which worked once I added the #override to my method.
So I've been stuck on this for hours. I'm trying to setup an async task that will load up an images for my listview in another class and I'm passing information that gives me an error
Any help would be appreciated!
public class TheResults extends Activity {
public static final String DEFAULTNAME = "DefaultFile";
private GETTHEIMAGE imgFetch;
private ArrayList<Item_Info> Info = new ArrayList<Item_Info>();
String Data = null;
String THESTRING = null;
TextView httpStuff;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// full screen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.theresults);
SharedPreferences Search = getSharedPreferences(DEFAULTNAME, 0);
Data = Search.getString("THERESULTS", null);
GetINFO();
populatelist();
}
private void GetINFO() {
}
}
}
private void populatelist() {
ArrayAdapter<Item_Info> adapter = new TheListAdapter();
ListView list = (ListView) findViewById(R.id.listings);
list.findFocus();
list.getWindowToken();
list.setAdapter(adapter);
}
public class TheListAdapter extends ArrayAdapter<Item_Info> {
public TheListAdapter() {
super(TheResults.this, R.layout.items, Info);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View item_View = convertView;
ImageHolder holder = null;
if (item_View == null) {
item_View = getLayoutInflater().inflate(R.layout.items, parent, false);
Item_Info CurrentItem = Info.get(position);
holder = new ImageHolder();
holder.ICON_IMG = (ImageView)item_View.findViewById(R.id.icon_image);
holder.ICON_IMG.setTag(CurrentItem.getItemPIC());
Drawable MYIMG = imgFetch.GetTheImagedata(this, holder.ICON_IMG);
holder.ICON_TITLE = (TextView)item_View.findViewById(R.id.icon_title);
holder.ICON_TITLE.setText(CurrentItem.getItemTITLE());
holder.ICON_LOCATION = (TextView)item_View.findViewById(R.id.icon_location);
holder.ICON_LOCATION.setText(CurrentItem.getItemLOCATION());
holder.ICON_PRICE = (TextView)item_View.findViewById(R.id.icon_price);
if (CurrentItem.getItemPRICE() == null) {
holder.ICON_PRICE.setText(CurrentItem.getItemPRICE());
holder.ICON_PRICE.setBackgroundResource(R.drawable.tempbg);
} else {
holder.ICON_PRICE.setBackgroundResource(R.drawable.pricebg);
holder.ICON_PRICE.setText(CurrentItem.getItemPRICE());
}
holder.ICON_DATE = (TextView)item_View.findViewById(R.id.icon_date);
holder.ICON_DATE.setText(CurrentItem.getItemLOCATION());
}else{
holder = (ImageHolder)item_View.getTag();
}
return item_View;
}
}
static class ImageHolder{
ImageView ICON_IMG;
TextView ICON_TITLE;
TextView ICON_LOCATION;
TextView ICON_PRICE;
TextView ICON_DATE;
}
}
By looking at the logcat after the line
06-21 19:15:06.887: E/AndroidRuntime(11408): FATAL EXCEPTION: main
is the exception
java.lang.NullPointerException
which tells us that something is null and that is throwing the exception. If we look for the first line of the code that references your project we will see where the problem occurs. Here, it happens to be the next line in logcat
at com.clistc.TheResults$TheListAdapter.getView(TheResults.java:178)
Which tells us that the line is 178 of TheResults.java and that it is inside the getView() method. We have established that it is this line
Drawable MYIMG = imgFetch.GetTheImagedata(this, holder.ICON_IMG);
which means that imgFetch is probably null and you try to call a function on it which returns null since the variable is null. I don't know what that variable is but it isn't being initialized before this line
Edit
imgFetch isn't initialized anywhere. It is declared here
private GETTHEIMAGE imgFetch;
but you never initialize it by giving it a value. You need to do something like
private GETTHEIMAGE imgFetch = new GETTHEIMAGE();
assuming it has an empty constructor
As a french developper, I apologize about my English.
So, my aim is to create a phone book for my android application. This phone book is made of a ListView. I've populated my ListView with a custom adapter which allows the user to select some TextViews in each rows.
I presume a picture is better than thousand words, so here it is:
As you can see the red parts are the TextViews that I have selected.
The issue I have to face is the following:
When I select a TextView from a row, the row that is 4 places under has its TextView that gets selected too! Is that a common issue or is it due to my code?
I've added a log on the click listener, for each TextView I click, I receive only one log, so I don't think the problem comes from my work.
For example and if some of you don't understand what I said; I select the TextView with the drawableLeft picture in the second row. The logcat returns me the following entry:
"Select: 1" (as defined in my code).
If I scroll down my ListView, I can see that my second row (ie. my TextView) is selected as expected but also my 6th row, which is not expected at all!
Here is the code I use in order to color or not a row:
public View getView(final int position, View convertView, ViewGroup parent)
{
selectedLocations.add(new Boolean(false));
selectedAvailabilities.add(new Boolean(false));
if (convertView == null) convertView = inflater.inflate(R.layout.phonebook_adapter_layout, parent, false);
final LinearLayout root = (LinearLayout) convertView.findViewById(R.id.phonebook_adapter_root);
final ImageView photo = (ImageView) convertView.findViewById(R.id.phonebook_adapter_image);
final TextView firstname = (TextView) convertView.findViewById(R.id.phonebook_adapter_firstname);
final TextView lastname = (TextView) convertView.findViewById(R.id.phonebook_adapter_lastname);
final TextView location = (TextView) convertView.findViewById(R.id.phonebook_adapter_location);
final TextView availability = (TextView) convertView.findViewById(R.id.phonebook_adapter_availability);
Bitmap mBitmap = null;
try
{
mBitmap = Media.getBitmap(context.getContentResolver(), Uri.parse(relations.get(position).getPhoto()));
photo.setImageBitmap(mBitmap);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
firstname.setText(relations.get(position).getFirstName());
lastname.setText(relations.get(position).getLastName());
DBStatus dbStatus = new DBStatus(KramerApplication.getInstance());
Status status = dbStatus.getWithRelation(relations.get(position));
dbStatus.close();
if (status != null)
{
location.setText( status.getLocation() );
availability.setText( status.getAvailability() );
if ( status.getDisplayedAvailability(2).equals("Busy") )
availability.setCompoundDrawablesWithIntrinsicBounds(R.drawable.availability_busy, 0, 0, 0);
else if ( status.getDisplayedAvailability(2).equals("Occupied") )
availability.setCompoundDrawablesWithIntrinsicBounds(R.drawable.availability_busy, 0, 0, 0);
else if ( status.getDisplayedAvailability(2).equals("Free") )
availability.setCompoundDrawablesWithIntrinsicBounds(R.drawable.availability_on, 0, 0, 0);
else
availability.setCompoundDrawablesWithIntrinsicBounds(R.drawable.availability_off, 0, 0, 0);
}
root.setOnClickListener(new OnClickListener() {
public void onClick(View v)
{
Intent intent = new Intent(context, ContactDetailsActivity.class);
intent.putExtra("contact_id", relations.get(position).getId());
context.startActivity(intent);
}
});
location.setOnClickListener(new OnClickListener() {
public void onClick(View v)
{
if (selectedLocations.get(position).booleanValue())
{
selectedLocations.set(position, new Boolean(false));
location.setBackgroundColor(Color.TRANSPARENT);
}
else
{
selectedLocations.set(position, new Boolean(true));
location.setBackgroundColor(Color.RED);
}
}
});
availability.setOnClickListener(new OnClickListener() {
public void onClick(View v)
{
if (selectedAvailabilities.get(position).booleanValue())
{
selectedAvailabilities.set(position, new Boolean(false));
availability.setBackgroundColor(Color.TRANSPARENT);
}
else
{
selectedAvailabilities.set(position, new Boolean(true));
availability.setBackgroundColor(Color.RED);
}
}
});
return convertView;
}
The ArrayLists "selectedAvailabilities" and "selectedLocations" have been properly initialized in the constructor and do their jobs when I use them in another activity (Read only).
I hope you'll be able to help me.
Regards.
V.
################################# SOLUTION
If someone is looking for the solution, here it is. Many thanks to user936414!.
Replace (line 6):
if (convertView == null) convertView = inflater.inflate(R.layout.phonebook_adapter_layout, parent, false);
By:
convertView = inflater.inflate(R.layout.phonebook_adapter_layout, parent, false);
Before:
return convertView;
Add:
if (selectedAvailabilities.get(position).booleanValue())
{
availability.setBackgroundColor(Color.RED);
}
if (selectedLocations.get(position).booleanValue())
{
location.setBackgroundColor(Color.RED);
}
The reason for this behavior is the use of convertview. To solve this, have a HashSet and put all the positions selected in the HashSet. In getView check contains of Hashset and setSelected for the TextView. Hope this helps.
Add
if (selectedLocations.get(position).booleanValue())
{
location.setBackgroundColor(Color.RED);
}
else
{
location.setBackgroundColor(Color.TRANSPARENT);
}
outside the onClickListener also to ensure convertView does not affect your requirement.
Updated code snipped as asked:
int MovieNum=children.size();
String[] MovieName=new String[MovieNum];
String[] MovieCover=new String[MovieNum];
RadioGroup rg = new RadioGroup (this);
rg = (RadioGroup) findViewById(R.id.radioGroup1);
RadioButton rb[]= new RadioButton[children.size()];
//LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
//LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
//layout.addView(rg, p);
for (int i = 0; i < children.size(); i++)
{
Element movieAtt = (Element)doc.getRootElement().getChild("movies").getChildren("movie").get(i);
MovieName[i]=movieAtt.getAttributeValue( "Title" );
MovieCover[i]=movieAtt.getAttributeValue( "cover" );
ShowTime[i]=movieAtt.getAttributeValue( "showtime" );
TweetText+=" I will see "+movieAtt.getAttributeValue("Title");
System.out.println(TweetText);
//ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.rowlayout, R.id.label, MovieName);
//setListAdapter(adapter);
//String item = (String) getListAdapter().getItem(position);
rb[i] = new RadioButton(this);
rb[i].setText(movieAtt.getAttributeValue("Title"));
rg.addView(rb[i]);
//Calling this func to get Images
//LoadImageFromWebOperations(movieAtt.getAttributeValue( "cover" ));
}
}
}
catch (MalformedURLException e1)
{
e1.printStackTrace();
System.out.println("ErrorThrowedIs: "+e1);
Toast.makeText(getBaseContext(), e1.toString(),5);
}
}
public static Drawable LoadImageFromWebOperations(String url)
{
try
{
InputStream is = (InputStream) new URL(url).getContent();
Drawable d = Drawable.createFromStream(is, "src name");
return d;
}
catch (Exception e)
{
return null;
}
}
//Updated code ends here
I have to display 3 things in my list View. One is going to be a Radio button corresponding to every row. I can not use Radio group as i am not aware of the list length which is dynamically generated. So i can not set it as Radio group.
I wish to know how can i do the same.
Also what i am doing is, i want to get an image along in the same list for every row which is created from the path i get at runtime.
So during my program, i would get these values :
for (int i = 0; i < mvLen; i++)
{
Element movieAtt = (Element)doc.getRootElement().getChild("movies").getChildren("movie").get(i);
MovieName[i]=movieAtt.getAttributeValue( "Title" );
MovieCover[i]=movieAtt.getAttributeValue( "cover" );
ShowTime[i]=movieAtt.getAttributeValue( "showtime" );
Now clearly this is an string array of Movie
Names in MovieName and array of strings of URL for the cover of that movie. I wish to display all those images in front of the Movie Names. My list adapter and corrosponding XML file are listed as below. Can anyone suggest changes/hints for the same . I have been reading http://www.vogella.de/articles/AndroidListView/article.html as well. But could not figure out much to meet my requirements.
So. Create RadioGroup in your class RadioGroup radioGroup = new RadioGroup(this); and simply add radiobuttons to it when you filling content radioGroup.addView(radioButton);
Summary:
RadioGroup radioGroup = new RadioGroup(this);
//Cycle begin
RadioButton rButton = (RadioButton)findViewById(R.id.my_radiobutton);
// OR
RadioButton radioButton = new RadioButton(this);
radioButton .setText(R.string.radio_group_snack);
radioButton .setId(R.id.snack);
radioGroup.addView(rButton);
radioGroup.addView(radioButton);
//Cycle end
Example of custom adapter and getview method(it's 100% work code):
public class MyCustomAdapter extends ArrayAdapter<String> {
public MyCustomAdapter(Context context, int textViewResourceId,
String[] objects) {
super(context, textViewResourceId, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String[] users = getUsers(); //it returns list of users in String array
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.main, parent, false);
TextView label=(TextView)row.findViewById(R.id.label); //TextView decalred in my layout xml file
label.setText(users[position]);
ImageView icon=(ImageView)row.findViewById(R.id.icon); //ImageView decalred in my layout xml file
byte[] bb = getAvatar(users[position]); //some method where I get image for user. It not interesting for us so I cut it from here...
if(bb != null && bb.length != 0){
icon.setImageBitmap(BitmapFactory.decodeByteArray(bb, 0, bb.length)); //SET IMAGE FOR ROW
icon.setVisibility(View.VISIBLE); //SET VISIBILITY OF IMAGE
}
//RIGHT HERE YOU CAN MANIPULATE WITH YOUR RADIOBUTTONS. FOR EXAMPLE:
RadioButton rButton = (RadioButton)findViewById(R.id.my_radio_button);
radioGroup.addView(rButton); //WHERE radioGroup IS RADIOGROUP YOU INITIALIZED BEFORE;
return row;
}
}
}
And this is my onCreate method:
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
db.open();
String[] users = db.getUsersList();
ListView listView = getListView();
this.setListAdapter(new MyCustomAdapter(this, R.layout.main, users));
db.close();
}
For each row in the list get the radioButton and add it to the RadioGroup.
You might have to create all the radioButton's upfront and store them in a list.Set them in the ContentView depending on the position