android finalizer never ends and collects old objects, is it normal? - android

my simple activity has got a listview holding 14 items(genre). when i run the app, i get the snapshot and there are one 1 GenreSelectionActivity and 14 Genre in the memory normally. then i pass to other activities and go back, there are 2 GenreSelectionActivity and 28 Genre. half of them coloured red, means in finalizerReference. then doing same navigation, it becomes 3 - 42 and so on. is it normal behaviour of finalizer?
i try to call "System.exit(0)" on destroy, old activity is cleaned but an annoying black screen appears on transition.
public class GenreSelectionActivity extends Activity {
Activity activity;
ListView listViewGenre;
GenreList genreList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.genre_list);
activity = this;
createGenrePlayButton();
listViewGenre = (ListView) findViewById(R.id.listGenre);
JSONObject jsonResponseGenres = s.readInternalStoragePrivate(Constants.GENRE_FILE_NAME, getApplicationContext());
JsonResolver jsonResolver = new JsonResolver();
genreList = jsonResolver.getGenreListWithPhasesFromJson(jsonResponseGenres);
final GenreCircularAdapter genreCircularAdapter = new GenreCircularAdapter(activity, R.layout.genre_row, genreList);
listViewGenre.setAdapter(genreCircularAdapter);
listViewGenre.setSelectionFromTop(genreCircularAdapter.MIDDLE, 0);
}
public void createGenrePlayButton() {
ImageView genrePlayButton = (ImageView) findViewById(R.id.genrePlayButton);
genrePlayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View view) {
Intent questPage = new Intent(activity, QuestionManagerActivity.class);
questPage.putExtra("genre_name", "pop");
Phase selectedPhaseData = new Phase();
selectedPhaseData.setHighScore(0);
questPage.putExtra("selected_phase_data", selectedPhaseData);
activity.startActivity(questPage);
activity.finish();
//System.exit(0);
}
});
}
}
this is the adapter i use:
public class GenreCircularAdapter extends ArrayAdapter<Genre> {
private GenreList genreList;
private Activity activity;
LayoutInflater inflater;
public static final int HALF_MAX_VALUE = Constants.GENRE_CIRCULAR_LISTVIEW_SIZE / 2;
public final int MIDDLE;
public GenreCircularAdapter(Activity activity, int resource, GenreList genreList) {
super(activity, resource, genreList);
this.genreList = genreList;
this.activity = activity;
inflater = LayoutInflater.from(activity);
MIDDLE = HALF_MAX_VALUE - HALF_MAX_VALUE % genreList.size();
}
#Override
public int getCount() {
return Constants.GENRE_CIRCULAR_LISTVIEW_SIZE;
}
#Override
public Genre getItem(int position) {
return genreList.get(position % genreList.size());
}
#Override
public long getItemId(int position) {
return genreList.get(position % genreList.size()).getId();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder genreRowHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.genre_row, parent, false);
genreRowHolder = new ViewHolder();
genreRowHolder.attachChildViews(convertView);
convertView.setTag(genreRowHolder);
} else
genreRowHolder = (ViewHolder) convertView.getTag();
Genre genre = getItem(position);
genreRowHolder.genreName.setText(genre.getName());
try {
int genreImageResID = activity.getResources().getIdentifier(String.valueOf("genre_" + genre.getId()), "drawable", activity.getPackageName());
genreRowHolder.genreImageView.setImageDrawable(activity.getResources().getDrawable(genreImageResID));
genreRowHolder.genreImageView.setColorFilter(0x96064e66, PorterDuff.Mode.SRC_ATOP);
} catch (Exception e){
Log.e("img_not_found", "genre_" + genre.getId() + " - " + getClass().getSimpleName());
}
return convertView;
}
private static class ViewHolder {
public TextView genreName;
public ImageView genreImageView;
public ImageView genreLockImageView;
public void attachChildViews (View convertView) {
genreName = (TextView) convertView.findViewById(R.id.genreName);
genreImageView = (ImageView) convertView.findViewById(R.id.genreImageView);
genreLockImageView = (ImageView) convertView.findViewById(R.id.genreLockImage);
}
}
}

i couldn't detect the problem. i tried that workaround, it seems troubleless for now.
#Override
protected void onDestroy() {
// remove all content view
((FrameLayout)findViewById(android.R.id.content)).removeAllViews();
// empty arraylist
genreList.clear();
genreList.trimToSize();
// call garbage collector (it may not effect anything)
Runtime.getRuntime().gc();
System.gc();
System.runFinalization();
}

Related

Listview add item one at a time

I have a listview and a button in my main activity and three layout ressource files (right.xml, mid.xml and left.xml [They're relative layout]).
I want to make an arrayList (with strings and drawable (images)) and each time I push the button in main.xml the first content of the arrayList will appear at the bottom of the screen (either left, mid or right --> depend of the order of the arrayList) and when I click again the next item (string or drawable) will appear beneath it, pushing it in an upward motion.
UPDATE
I made a Model and an Adapter
Here is the model
public class ModelC1 {
public String C1Name;
public String C1Text;
public int id;
public boolean isSend;
public ModelC1(String C1Name, String C1Text, int id, boolean isSend){
this.id = id;
this.C1Name = C1Name;
this.C1Text = C1Text;
this.isSend = isSend;
}
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
public String getC1Name() {
return C1Name;
}
public void setC1Name(String C1Name){
this.C1Name = C1Name;
}
public String getC1Text() {
return C1Text;
}
public void setC1Text (String C1Text){
this.C1Text = C1Text ;
}
public boolean isSend() {
return isSend;
}
public void setIsSend(boolean send){
isSend = send;
}
Here is the Adapter
public class AdapterC1 extends BaseAdapter {
private List<ModelC1> listChat;
private LayoutInflater inflater;
private Context context;
public AdapterC1(List<ModelC1> listChat, Context context){
this.listChat = listChat;
this.context = context;
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return listChat.size();
}
#Override
public Object getItem(int i) {
return listChat.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
View vi = convertView;
if(convertView == null ){
if(listChat.get(i).isSend() == 0)
vi=inflater.inflate(R.layout.list_send,null);
else if ((listChat.get(i).isSend() == 1))
vi=inflater.inflate(R.layout.list_recv,null);
else if ((listChat.get(i).isSend() == 2))
vi=inflater.inflate(R.layout.list_mid,null);
}else{
if(listChat.get(i).isSend() == 0)
vi=inflater.inflate(R.layout.list_send,null);
else if ((listChat.get(i).isSend() == 1))
vi=inflater.inflate(R.layout.list_recv,null);
else if ((listChat.get(i).isSend() == 2))
vi=inflater.inflate(R.layout.list_mid,null);
}
if(listChat.get(i).isSend() !=0 || listChat.get(i).isSend() !=1 || listChat.get(i).isSend() !=2 ){
BubbleTextView bubbleTextView = (BubbleTextView) vi.findViewById(R.id.bubbleChat);
if(bubbleTextView != null)
bubbleTextView.setText(listChat.get(i).C1Text);
TextView nameTextView = (TextView) vi.findViewById(R.id.nameChat);
if(nameTextView != null)
nameTextView.setText(listChat.get(i).C1Name);
}else{
vi=inflater.inflate(R.layout.list_mid,null);
BubbleTextView bubbleTextView = (BubbleTextView) vi.findViewById(R.id.bubbleChat);
bubbleTextView.setText("THE END");
}
return vi;
}
And here is the activity
public class Chat1 extends AppCompatActivity {
private static final String TAG = "Chat1";
private AdapterC1 adapter;
private List<ModelC1> listChat = new ArrayList<>();
private int count = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat1);
RecyclerView chatContent1 = findViewById(R.id.chatContent1);
}
private ModelC1 setUpMessage(){
Log.d(TAG, "setUpMessage: Exec");
return();
}
///OnClick of the button in the activity_chat1.xml
public void nextClicked1(View view) {
Log.d(TAG, "nextClicked: Is Clicked");
///After the limit of the arraylist is reached
final int limit = 40;
if(count == limit){
Log.d(TAG, "nextClicked: Limit Reached");
Intent i = new Intent(Chat1.this, MainActivity.class);
startActivity(i);
}else{
///Call the list
loadList(null);
}
}
///Load the list of arrays?
public void loadList(View view){
ModelC1 chat = setUpMessage();
listChat.add(chat);
///The ID of the recycleview in the activity_chat1.xml
final RecyclerView recyclerview = findViewById(R.id.chatContent1);
///The adapter
final AdapterC1 adapter = new AdapterC1(listChat, this);
///Make the recyclerview always scroll
///the adapter
///recyclerview.setAdapter(adapter);
}
My questions are now how do I make the ArrayList (containing strings and drawables) and how to link the ArrayList to make it appear one by one when I click on the button ?
As for the ArrayList, will soemthing like that works ?
private List<List<String>> textChat1 = new ArrayList<List<String>>();
ArrayList<String> textChat1 = new ArrayList<String>();
textChat1.add("This is message 1");
textChat1.add("This is message 2");
textChat1.add("This is message 2");
addresses.add(textChat1);
How can I add images and how to say which strings inflate which layout (left, mid or right) ?
You can do your job like this: in your Adapter's getView method ,
#Override
public View getView(int position, View convertView, ViewGroup container) {
if (convertView == null) {
if (position == 1) {
convertView = getLayoutInflater().inflate(R.layout.left, container, false);
} else if (position == 2) {
convertView = getLayoutInflater().inflate(R.layout.mid, container, false);
} else {
convertView = getLayoutInflater().inflate(R.layout.right, container, false);
}
}
//your code here
return convertView;
}
This will do your job, but, I suggest you to use Recyclerview because it's more efficient and better in terms of looks as well as memory management.

Android ListView glitching back to top for a few seconds before it works properly

I am trying to make an application with a ListView that include a Country Flag and name. This is so that the user can click on them and be shown images of the country that they wouldve taken before. However for about 3 seconds when the listview loads if i try to scroll it will sort of glitch and send me back to top. This is the code..
public class CountriesListAdapter extends ArrayAdapter {
private int resource;
private LayoutInflater inflater;
private List<CountryModel> countryModels;
private WeakReference<TextView> selectedCountryIdtxt;
private boolean useFilter;
private WeakReference<ProgressBar> progressBarWeakReference;
public int getSelectedCountryId() {
return selectedCountryId;
}
public void setSelectedCountryId(int selectedCountryId) {
this.selectedCountryId = selectedCountryId;
}
private int selectedCountryId;
public CountriesListAdapter(#NonNull WeakReference<Context> context, int resourceId, WeakReference<TextView> textView, #NonNull List<CountryModel> countryModelList, boolean useFilter, WeakReference<ProgressBar> progressBarWeakReference){
super(context.get(), resourceId, countryModelList);
selectedCountryIdtxt = textView;
resource = resourceId; //the id of the template file
inflater = LayoutInflater.from(context.get());
this.countryModels = countryModelList;
selectedCountryId = -1;
this.useFilter = useFilter;
this.progressBarWeakReference = progressBarWeakReference;
}
public int getCount() {
if (countryModels != null)
return countryModels.size();
return 0;
}
public CountryModel getItem(int position) {
if (countryModels != null)
return countryModels.get(position);
return null;
}
public long getItemId(int position) {
if (countryModels != null)
return countryModels.get(position).hashCode();
return 0;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
// this method is automatically called for every object in our list
//basically it's called for every single row before it is generated
// this method is called per row
convertView = (ConstraintLayout) inflater.inflate(resource, null);
//the variable countryModel is fiiled with current object that is being processed
final CountryModel countryModel = countryModels.get(position);
TextView countryName = convertView.findViewById(R.id.countryNamelbl);
final ImageView countryFlag = convertView.findViewById(R.id.countryFlagimg);
final ImageView checked = convertView.findViewById(R.id.countryCheckedimg);
//this is done for every object in the list
assert countryModel != null;
countryName.setText(countryModel.getName());
Picasso.get().load(countryModel.getImage()).fit().into(countryFlag);
if(!useFilter) {
if (selectedCountryId == countryModel.getId()) {
checked.setVisibility(View.VISIBLE);
} else {
checked.setVisibility(View.INVISIBLE);
}
}
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(!useFilter) {
if (checked.getVisibility() == View.VISIBLE) {
checked.setVisibility(View.INVISIBLE);
selectedCountryId = -1;
selectedCountryIdtxt.get().setText(String.valueOf(selectedCountryId));
} else {
if (selectedCountryId == -1) {
checked.setVisibility(View.VISIBLE);
selectedCountryId = countryModel.getId();
} else {
selectedCountryId = countryModel.getId();
notifyDataSetChanged();
}
selectedCountryIdtxt.get().setText(String.valueOf(selectedCountryId));
}
} else {
Intent i = new Intent(getContext(), PicturesActivity.class);
i.putExtra("countryId",countryModel.getId());
i.putExtra("countryName", countryModel.getName());
getContext().startActivity(i);
}
}
});
progressBarWeakReference.get().setVisibility(View.INVISIBLE);
return convertView;
}
public List<CountryModel> getCountryModels() {
return countryModels;
}
public void setCountryModels(List<CountryModel> countryModels) {
this.countryModels = countryModels;
}
}
The problem was actually in another class, i was calling the adapter for every list item instead of just once... oops.
Thanks for the replies though!

custom listview repeat last row

hi i want to get values from database and show in listview
i get 6 value from database and send it to adapter but all 6 row is last item to send to adapter
when i add
ViewHolder holder;
android studio after alt + enter change to
RecyclerView.ViewHolder holder;
i read this post's but can not fix problem
Rows being repeated in ListView
Duplicated entries in ListView
Android Listview row repeating item
List item repeating in android customized listview
I know this question is duplicate but can not fix it
Thanks in advance
my adapter :
public class lim_sms_adapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<lim_sms> lim_smsItems;
public lim_sms_adapter (Activity activity, List<lim_sms> lim_smsItems) {
this.activity = activity;
this.lim_smsItems = lim_smsItems;
}
#Override
public int getCount() {
return lim_smsItems.size();
}
#Override
public Object getItem(int location) {
return lim_smsItems.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getViewTypeCount() {
return getCount();
}
#Override
public int getItemViewType(int position) {
return position;
}
#SuppressLint("SetTextI18n")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.row_lim_sms, null);
TextView number = (TextView) convertView.findViewById(R.id.row_lim_sms_txt_number);
lim_sms m = lim_smsItems.get(position);
number.setText(m.getSms_number());
return convertView;
}
}
my class seter and geter :
public class lim_sms {
String sms_number;
public lim_sms(String sms_number) {
this.sms_number = sms_number;
}
public lim_sms() {
}
public String getSms_number() {
return sms_number;
}
public void setSms_number(String sms_number) {
this.sms_number = sms_number;
}
}
my activity :
public class list_limit_sms extends AppCompatActivity {
private List<lim_sms> limit_sms = new ArrayList<lim_sms>();
private lim_sms_adapter adapter;
private sms_database sms_db = new sms_database(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_limit_sms);
ListView listView = (ListView) findViewById(R.id.list_lim_sms);
adapter = new lim_sms_adapter(this, limit_sms);
listView.setAdapter(adapter);
lim_sms cy = new lim_sms();
List<sms_class> sms_list = sms_db.getAllContacts();
for (sms_class ss : sms_list) {
//String log = "Id: "+ss.getId()+" ,num: " + ss.getNum() + " ,type: " + ss.getType();
//Toast.makeText(this, ""+log, Toast.LENGTH_LONG).show();
cy.setSms_number(ss.getNum());
Toast.makeText(this, ""+ss.getNum(), Toast.LENGTH_SHORT).show();
limit_sms.add(cy);
adapter.notifyDataSetChanged();
}
}
}

ListView disappears after reloading it again

I have 3 arraylist that i have combined to show in listview. Wehen i click on to generate listview, it works fine the first time but when i hit back and then click the button again, the listview shows nothing. Not sure what is cause it. I checked other post but couldnt find an answer. I am not too good with Arraylist so any details would be greatly appreciated.
I have also noticed this message in Log cat. not sure what it means.
onVisibilityChanged() is called, visibility : 0
public class Edit extends Activity implements OnItemClickListener {
private int pic;
public String filename ="User Info";
//Declaring SHareddPreference as userprofile
static SharedPreferences userprofile;
ListView listView;
List<RowItem> rowItems;
// String[] titles, descriptions;
File imgpath=null;
Context context=this;
CustomListAdapter adapter;
private List<String> Titles = new ArrayList<String>();
private List<String> Actions = new ArrayList<String>();
private List<Bitmap> Images = new ArrayList<Bitmap>();
int x;
int y=1;
int z=1;
static int a=1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aname);
listView = (ListView)findViewById(R.id.listing);
userprofile = getSharedPreferences(filename,0);
Intent pdf=getIntent();
pic= userprofile.getInt("lastpic",pic);
x=pic;
Log.d("editpic",new Integer(pic).toString());
while(y!=x){
String comment = commentresult();
Titles.add(comment);
y++;
Log.d("y",new Integer(y).toString());
}
while(z!=x){
String act = actionresult();
Actions.add(act);
z++;
Log.d("z",new Integer(z).toString());}
while(a!=x){
Bitmap photo = getbitmap();
Images.add(photo);
a++;
Log.d("a",new Integer(a).toString());}
Titles.toArray();
Actions.toArray();
Images.toArray();
rowItems = new ArrayList<RowItem>();
for (int i = 0; i < Images.size(); i++) {
RowItem item = new RowItem(Images.get(i), Titles.get(i),Actions.get(i));
rowItems.add(item);
}
Log.d("TAG", "listview null? " + (listView == null));
CustomListAdapter adapter = new CustomListAdapter(this,
R.layout.aname_list_item, rowItems);
Log.d("TAG", "adapter=null? " + (adapter == null));
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
listView.setOnItemClickListener(this);
}
public static Bitmap getbitmap() {
String photo1 =userprofile.getString("picpath"+a, "");
File imgpath=new File(photo1);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Bitmap bmp=DecodeImage.decodeFile(imgpath, 800, 1000, true);
bmp.compress(Bitmap.CompressFormat.JPEG, 100 , stream);
Bitmap photo2=bmp;
return photo2;
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast toast = Toast.makeText(getApplicationContext(),
"Item " + (position + 1) + ": " + rowItems.get(position),
Toast.LENGTH_SHORT);
toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0);
toast.show();
}
public String commentresult()
{
// String com2 = null;
// while(y!=x){
String comment=userprofile.getString("comment"+y, "");
String com1=comment;
String com2=com1;
// }
return com2;
}
public String actionresult()
{
// String act2 = null;
// while(y!=x){
String action=userprofile.getString("action"+z, "");
String act1=action;
String act2=act1;
// }
return act2;
}
private static final long delay = 2000L;
private boolean mRecentlyBackPressed = false;
private Handler mExitHandler = new Handler();
private Runnable mExitRunnable = new Runnable() {
#Override
public void run() {
mRecentlyBackPressed=false;
}
};
#Override
public void onBackPressed() {
//You may also add condition if (doubleBackToExitPressedOnce || fragmentManager.getBackStackEntryCount() != 0) // in case of Fragment-based add
if (mRecentlyBackPressed) {
mExitHandler.removeCallbacks(mExitRunnable);
mExitHandler = null;
super.onBackPressed();
}
else
{
mRecentlyBackPressed = true;
Toast.makeText(this, "press again to exit", Toast.LENGTH_SHORT).show();
mExitHandler.postDelayed(mExitRunnable, delay);
}
}
#Override
public void onDestroy() {
// Destroy the AdView.
super.onDestroy();
}
Custom List Adapter:
public class CustomListAdapter extends ArrayAdapter<RowItem> {
Context context;
List<RowItem> items;
public CustomListAdapter(Context context, int resourceId,
List<RowItem> items) {
super(context, resourceId, items);
this.context = context;
this.items = items;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return items.size();
}
#Override
public RowItem getItem(int position) {
// TODO Auto-generated method stub
return items.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
/*private view holder class*/
private class ViewHolder {
ImageView imageView;
TextView txtTitle;
TextView txtDesc;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
RowItem rowItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.aname_list_item, null);
holder = new ViewHolder();
holder.txtDesc = (TextView) convertView.findViewById(R.id.desc);
holder.txtTitle = (TextView) convertView.findViewById(R.id.rab);
holder.imageView = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
// String name=items.get(position).getDesc();
holder.txtDesc.setText(rowItem.getDesc());
holder.txtTitle.setText(rowItem.getTitle());
holder.imageView.setImageBitmap(rowItem.getImageId());
// holder.imageView.setImageResource(Images.get(position) .getPlaceholderleft());
return convertView;
}
}
It looks like this is because you've made your variables x, y, z and a all static, which means there is a single instance of the variables shared by all instances of the class. Therefore, when you call onCreate the second time, all your while loop termination conditions are already met, so the while loops never execute. It's unclear to me why you've made these static, so unless you need them to be, you should remove the static keyword for these variables.
Why are you creating another object of ListView in onCreate() and onResume()
Remove code from onResume()
Also replace this line in onCreate()
old line ListView listView = (ListView)findViewById(R.id.listing);
New line listView = (ListView)findViewById(R.id.listing);

Custom arrayAdapter with listFragment

I'm trying to make a ListFragment. I looked the Api Demo (FragmentLayout). it works on a simple example and now i want to apply it to my existing project.
Here is my code. I create inner classes (RecipeList & RecipeDetail) as in the Api Demo.
public class InfoActivity extends MenuActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.info_fragment_layout);
// ...
}
public static class RecipeList extends ListFragment {
private int mCurrentSelectedItemIndex = -1;
private boolean mIsTablet = false;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
accountData = new ArrayList<Account>();
new AccountSyncTask() {
#Override
public void onPostExecute(
final ArrayList<ArrayList<String>> result) {
// For each retrieved account
Bd.insert(retrievedAccount);
accountData.add(retrievedAccount);
}
accountListAdapter = new AccountListAdapter(
InfoActivity.this, R.layout.accountlist_detail,
accountData);
accountListAdapter = new AccountListAdapter(
activityContext, R.layout.accountlist_detail,
accountData);
setListAdapter(accountListAdapter);
}
}.execute(sessionName, null, "getAllObjectOnServer",
String.valueOf(nbRow));
if (savedInstanceState != null) {
mCurrentSelectedItemIndex = savedInstanceState.getInt(
"currentListIndex", -1);
}
// This is a tablet if this view exists
View recipeDetails = getActivity()
.findViewById(R.id.recipe_details);
mIsTablet = recipeDetails != null
&& recipeDetails.getVisibility() == View.VISIBLE;
if (mIsTablet) {
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
if (mIsTablet && mCurrentSelectedItemIndex != -1) {
showRecipeDetails();
}
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
mCurrentSelectedItemIndex = position;
showRecipeDetails();
}
private void showRecipeDetails() {
if (mIsTablet) {
// Set the list item as checked
getListView().setItemChecked(mCurrentSelectedItemIndex, true);
// Get the fragment instance
RecipeDetail details = (RecipeDetail) getFragmentManager()
.findFragmentById(R.id.recipe_details);
// Is the current visible recipe the same as the clicked? If so,
// there is no need to update
if (details == null
|| details.getRecipeIndex() != mCurrentSelectedItemIndex) {
details = RecipeDetail
.newInstance(mCurrentSelectedItemIndex);
FragmentTransaction ft = getFragmentManager()
.beginTransaction();
ft.replace(R.id.recipe_details, details);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
} else {
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("currentListIndex", mCurrentSelectedItemIndex);
}
}
public static class RecipeDetail extends Fragment {
private int mRecipeIndex;
public static RecipeDetail newInstance(int recipeIndex) {
// Create a new fragment instance
RecipeDetail detail = new RecipeDetail();
// Set the recipe index
detail.setRecipeIndex(recipeIndex);
return detail;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
return null;
}
View v = inflater
.inflate(R.layout.recipe_details, container, false);
//..
return v;
}
public int getRecipeIndex() {
return mRecipeIndex;
}
public void setRecipeIndex(int index) {
mRecipeIndex = index;
}
}
I have a custom ArrayAdapter (my items in the ListFragment contain 4 textViews and a clickable imageButton).
AccountListAdapter :
public class AccountListAdapter extends ArrayAdapter<Account> {
private final Context context;
private final int layoutResourceId;
private final ArrayList<Account> data;
public AccountListAdapter(Context context, int layoutResourceId,
ArrayList<Account> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
AccountHolder holder = null;
if (convertView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
convertView = inflater.inflate(layoutResourceId, parent, false);
holder = new AccountHolder();
convertView.setClickable(true);
convertView.setFocusable(true);
holder.txtName = (TextView) convertView.findViewById(R.id.nom);
holder.txtId = (TextView) convertView.findViewById(R.id.id);
convertView.setTag(holder);
} else {
holder = (AccountHolder) convertView.getTag();
}
convertView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.i("click", "index = " + position);
}
});
holder.txtName.setText(data.get(position).getName());
holder.txtId.setText(data.get(position).getId());
convertView.setBackgroundResource(R.drawable.list_selector);
ImageButton img = (ImageButton) convertView.findViewById(R.id.check);
img.setTag(position);
return convertView;
}
static class AccountHolder {
TextView txtName;
TextView txtId;
}
}
Problem :
When i click on an Item of the listFragment,
public void onListItemClick(ListView l, View v, int position, long id) {
mCurrentSelectedItemIndex = position;
Log.i("click", "here";
showRecipeDetails();
}
is not called but the listener on an item defined in AccountListAdapter works
convertView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.i("click", "index = " + position);
}
});
Why is onListitemClick never called ?
Another question : is it a proper way to consume a web service in another thread in the onActivityCreated function of my ListFragment (in order to populate the list) ?
Thx in advance
EDIT = For the moment i made "showRecipeDetails" static and call it in the listener in my custom ArrayAdapter.
convertView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
RecipeList.showRecipeDetails(position);
}}
I'm not satisfied with my solution, i'm interessed to any other solution
OnItemClickListeners must first be associated with the ListView you want to record clicks for. In your onActivityCreated(..) method, place getListView().setOnItemClickListener(this) somewhere and put implements OnItemClickListener after public static class RecipeList extends ListFragment.

Categories

Resources