getArgument().getInt() returns null - java

I just started programming and I don't know much, so I apologize if what I'm asking is obvious.
I'm making an icon pack dashboard app and I'm copy & pasting code from open source templates into my projects. I know it isn't the best thing to do, but I'm just trying to understand how complex things work.
I've read some similar issues, but I'd need a step-by-step guide.
Now, I'm facing this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.os.Bundle.getInt(java.lang.String, int)' on a null object reference
at com.squaredlab.oblivion.app.Fragment.IconsFragment$IconAdapter.loadIcon(IconsFragment.java:117)
at com.squaredlab.oblivion.app.Fragment.IconsFragment$IconAdapter.<init>(IconsFragment.java:50)
at com.squaredlab.oblivion.app.Fragment.IconsFragment.onCreateView(IconsFragment.java:30)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:955)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:458)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5372)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
I don't know what the problem is. The open source project I'm looking at works like a charm, obviously.
This is the code:
public class IconsFragment extends Fragment {
private String[] iconsnames;
public IconAdapter icAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
icAdapter = new IconAdapter();
View view = inflater.inflate(R.layout.icons_grid, container, false);
GridView gridview = (GridView) view.findViewById(R.id.icons_grid);
gridview.setColumnWidth(convertToPixel(72) + convertToPixel(4));
gridview.setAdapter(icAdapter);
return view;
}
public static IconsFragment newInstance(int iconsArray) {
IconsFragment fragment = new IconsFragment();
Bundle args = new Bundle();
args.putInt("iconsArrayId", iconsArray);
fragment.setArguments(args);
return fragment;
}
private class IconAdapter extends BaseAdapter {
private ArrayList<Integer> mThumbs;
public IconAdapter() {
loadIcon();
}
#Override
public int getCount() {
return mThumbs.size();
}
#Override
public Object getItem(int position) {
return mThumbs.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
IconsHolder holder;
Animation anim = AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in);
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(getActivity());
convertView = inflater.inflate(R.layout.item_icon, parent, false);
holder = new IconsHolder(convertView);
convertView.setTag(holder);
} else {
holder = (IconsHolder) convertView.getTag();
}
holder.icon.startAnimation(anim);
holder.icon.setImageResource(mThumbs.get(position));
holder.content.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View dialogIconView = View.inflate(getActivity(), R.layout.dialog_icon, null);
ImageView dialogIcon = (ImageView) dialogIconView.findViewById(R.id.dialogicon);
dialogIcon.setImageResource(mThumbs.get(position));
String name = iconsnames[position].toLowerCase(Locale.getDefault());
new MaterialDialog.Builder(getActivity())
.customView(dialogIconView, false)
.title(convertText(name))
.positiveText(R.string.close)
.show();
}
});
return convertView;
}
class IconsHolder {
final ImageView icon;
final MaterialRippleLayout content;
IconsHolder(View v) {
icon = (ImageView) v.findViewById(R.id.icon_img);
content = (MaterialRippleLayout) v.findViewById(R.id.icons_ripple);
}
}
private void loadIcon() {
mThumbs = new ArrayList<>();
final Resources resources = getResources();
final String packageName = getActivity().getApplication().getPackageName();
addIcon(resources, packageName, getArguments().getInt("iconsArrayId", 0));
}
private void addIcon(Resources resources, String packageName, int list) {
iconsnames = resources.getStringArray(list);
for (String extra : iconsnames) {
int res = resources.getIdentifier(extra, "drawable", packageName);
if (res != 0) {
final int thumbRes = resources.getIdentifier(extra, "drawable", packageName);
if (thumbRes != 0)
mThumbs.add(thumbRes);
}
}
}
}
private int convertToPixel(int dp) {
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
getActivity().getResources().getDisplayMetrics());
return (int) px;
}
private String convertText(String name) {
String partialConvertedText = name.replaceAll("_", " ");
String[] text = partialConvertedText.split("\\s+");
StringBuilder sb = new StringBuilder();
if (text[0].length() > 0) {
sb.append(Character.toUpperCase(text[0].charAt(0))).append(text[0].subSequence(1, text[0].length()).toString().toLowerCase());
for (int i = 1; i < text.length; i++) {
sb.append(" ");
sb.append(Character.toUpperCase(text[i].charAt(0))).append(text[i].subSequence(1, text[i].length()).toString().toLowerCase());
}
}
return sb.toString();
}
This is where I instantiate the Fragment (3rd case of the switch)
public class SimpleHeaderDrawerActivity extends AppCompatActivity {
//save our header or result
private AccountHeader headerResult = null;
private Drawer result = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample_fragment_dark_toolbar);
// Handle Toolbar
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the AccountHeader
headerResult = new AccountHeaderBuilder()
.withActivity(this)
.withHeaderBackground(R.drawable.header)
.withSavedInstance(savedInstanceState)
.build();
//Create the drawer
result = new DrawerBuilder()
.withActivity(this)
.withToolbar(toolbar)
.withAccountHeader(headerResult) //set the AccountHeader we created earlier for the header
.addDrawerItems(
new PrimaryDrawerItem().withName(R.string.drawer_item_home).withIcon(FontAwesome.Icon.faw_home),
new PrimaryDrawerItem().withName(R.string.drawer_item_launchers).withIcon(FontAwesome.Icon.faw_star),
new PrimaryDrawerItem().withName(R.string.drawer_item_wallpapers).withIcon(FontAwesome.Icon.faw_image),
new PrimaryDrawerItem().withName(R.string.drawer_item_takealook).withIcon(FontAwesome.Icon.faw_search),
new PrimaryDrawerItem().withName(R.string.drawer_item_iconlist).withIcon(FontAwesome.Icon.faw_sort_alpha_asc),
new PrimaryDrawerItem().withName(R.string.drawer_item_requesticons).withIcon(FontAwesome.Icon.faw_edit),
new SectionDrawerItem().withName(R.string.drawer_item_section_header),
new SecondaryDrawerItem().withName(R.string.drawer_item_settings).withIcon(FontAwesome.Icon.faw_cog),
new SecondaryDrawerItem().withName(R.string.drawer_item_help).withIcon(FontAwesome.Icon.faw_question).setEnabled(false),
new SecondaryDrawerItem().withName(R.string.drawer_item_contact).withIcon(FontAwesome.Icon.faw_bullhorn)
) // add the items we want to use with our Drawer
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
#Override
public boolean onItemClick(AdapterView<?> parent, View view, int position, long id, IDrawerItem drawerItem) {
if (drawerItem != null && drawerItem instanceof Nameable) {
getSupportActionBar().setTitle(((Nameable) drawerItem).getNameRes());
//ignore the DemoFragment and it's layout it's just to showcase the handle with an keyboard
Fragment f = DemoFragment.newInstance(getResources().getString(((Nameable) drawerItem).getNameRes()));
switch (position) {
//case 0:
// f = new IconListFragment();
// break;
//case 1:
// f = new IconListFragment();
// break;
case 2:
f = new WallpapersFragment();
break;
case 3:
f = new IconsFragment();
break;
//case 4:
// f = new IconListFragment();
// break;
//case 5:
// f = new IconListFragment();
// break;
//case 6;
//startActivity(new Intent(this, RequestActivity.class));
//break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, f).commit();
}
return false;
}
})
.withOnDrawerListener(new Drawer.OnDrawerListener() {
#Override
public void onDrawerOpened(View drawerView) {
}
#Override
public void onDrawerClosed(View drawerView) {
}
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
}
})
.withFireOnInitialOnClick(true)
.withSavedInstance(savedInstanceState)
.build();
//react on the keyboard
result.keyboardSupportEnabled(this, true);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
//add the values which need to be saved from the drawer to the bundle
outState = result.saveInstanceState(outState);
super.onSaveInstanceState(outState);
}
#Override
public void onBackPressed() {
//handle the back press :D close the drawer first and if the drawer is closed close the activity
if (result != null && result.isDrawerOpen()) {
result.closeDrawer();
} else {
super.onBackPressed();
}
}

You are not calling IconsFragment.newInstance() at all!
Instead of
case 3:
f = new IconsFragment();
break;
Do this
case 3:
f = IconsFragment.newInstance(*provide int value here*);
break;

maybe you do not setArguments in IconsFragment.newInstance method. Do you call it? http://developer.android.com/reference/android/app/Fragment.html#getArguments()

Related

Viewpager displaying the required details only once and not displaying it a second time when coming back from main screen

I am calling ViewPager(Fragment C) from a ListView(Fragment A). But this only works once. If I move back to my list and select another item , it doesnot move into the listview. It just shows a blank layout of fragment c.
Below is the code for Fragment A:
public class FragmentA extends Fragment implements AdapterView.OnItemClickListener{
ListView list;
Communicator communicator;
ArrayList<Book> book_a;
ArrayList<String> book_titles;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.fragment_a,container,false);
savedInstanceState = getArguments();
if (getArguments() != null) {
// savedInstanceState = getArguments();
book_a = (ArrayList<Book>) getArguments().getSerializable("bookarray");
book_titles = getList(book_a);
//Log.d("Frag_a:Title",book_a.get(5).getTitle());
list= (ListView) view.findViewById(R.id.listview);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,book_titles);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
}
return view;
}
public ArrayList<String> getList(ArrayList<Book> book2){
ArrayList<String> list_titles = new ArrayList<String>();
int size = book2.size();
for(int i=0;i<size;i++){
Book object;
object = book2.get(i);
list_titles.add(object.title);
}
return list_titles;
}
public void setCommunicator(Communicator communicator)
{
this.communicator = communicator;
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
communicator.respond(position);
}
public interface Communicator{
public void respond(int index);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if(context instanceof Communicator){
communicator = (Communicator) context;
} else {
throw new RuntimeException(context.toString()+"must implement Communicator");
}
}
#Override
public void onDetach() {
super.onDetach();
communicator = null;
}
}
Below is the code for MainActivity:
public class MainActivity extends AppCompatActivity implements FragmentA.Communicator{
FragmentB f2;
ArrayList<Book> b = new ArrayList<Book>();
FragmentManager manager;
static int flag = 0;
static String search="great";
SearchView sv ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sv = (SearchView) findViewById(R.id.searchView);
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
flag = 1;
search = query;
getBooks();
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
getBooks();
return false;
}
});
getBooks();
/*
manager = getSupportFragmentManager();
f1 = (FragmentA) manager.findFragmentById(R.id.fragment);
f1.setCommunicator(this);*/
}
#Override
public void respond(int index) {
f2 = (FragmentB) manager.findFragmentById(R.id.fragment2);
if(f2!=null && f2.isVisible())
{
f2.changeData(index);
}
else
{
Bundle bundle = new Bundle();
bundle.putInt("index", index);
bundle.putSerializable("bookarray",(ArrayList<Book>)b);
Fragment newFragment = new FragmentC();
newFragment.setArguments(bundle);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
public void afterGetBooks(ArrayList<Book> bks) {
for (Book h : bks) {
b.add(h);
}
manager = getSupportFragmentManager();
Bundle args = new Bundle();
args.putSerializable("bookarray",(ArrayList<Book>)bks);
FragmentA f1 = new FragmentA();
f1.setArguments(args);
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment,f1);
transaction.addToBackStack(null);
transaction.commit();
f1.setCommunicator(this);
}
private void getBooks(){
String url;
if(flag==0){
url = "https://kamorris.com/lab/audlib/booksearch.php/";}
else{
url = "https://kamorris.com/lab/audlib/booksearch.php?search=" + search;
flag=0;
}
//ArrayList<Book> boo;
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://kamorris.com/lab/audlib/booksearch.php/").addConverterFactory(GsonConverterFactory.create()).build();
Book.API api = retrofit.create(Book.API.class);
Call<ArrayList<Book>> call = api.getBooks(url);
call.enqueue(new Callback<ArrayList<Book>>() {
#Override
public void onResponse(Call<ArrayList<Book>> call, Response<ArrayList<Book>> response) {
ArrayList<Book> Books = response.body();
for(Book h: Books){
Log.d("Retro-Title",h.getTitle());
//b.add(h);
}
afterGetBooks(Books);
}
#Override
public void onFailure(Call<ArrayList<Book>> call, Throwable t) {
Toast.makeText(getApplicationContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
Below is the code for Fragment C:
public class FragmentC extends Fragment {
ViewPager vp;
static int list_pos;
FragmentPagerAdapter adapterViewPager;
public static ArrayList<Book> book_c;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_c,container,false);
if(getArguments()!= null){
book_c = (ArrayList<Book>) getArguments().getSerializable("bookarray");
list_pos = getArguments().getInt("index");
}
vp = (ViewPager) view.findViewById(R.id.viewpager);
adapterViewPager = new MyPagerAdapter(getFragmentManager());
vp.setAdapter(adapterViewPager);
return view;
}
public static class MyPagerAdapter extends FragmentPagerAdapter {
private static int NUM_ITEMS = 11;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
#Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
switch (list_pos) {
case 0: // Fragment # 0 - This will show FirstFragment
list_pos = position;
return FragmentB.newInstance(book_c,0);
case 1: // Fragment # 0 - This will show FirstFragment different title
list_pos = position;
return FragmentB.newInstance(book_c,1);
case 2: // Fragment # 1 - This will show SecondFragment
list_pos = position;
return FragmentB.newInstance(book_c,2);
case 3: list_pos = position;
return FragmentB.newInstance(book_c,3);
case 4:list_pos = position;
return FragmentB.newInstance(book_c,4);
case 5:list_pos = position;
return FragmentB.newInstance(book_c,5);
case 6:list_pos = position;
return FragmentB.newInstance(book_c,6);
case 7:list_pos = position;
return FragmentB.newInstance(book_c,7);
case 8:list_pos = position;
return FragmentB.newInstance(book_c,8);
case 9:list_pos = position;
return FragmentB.newInstance(book_c,9);
default:
return null;
}
}
// Returns the page title for the top indicator
#Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
}
}
}
Also is there a way, where I can start my viewpager from the description of the listitem which I selected.
Also Fragment B is just a text view holder.
I tried to see the control flow with the debugger. But when I try it that way these lines in Fragment C are not working ..
{
book_c = (ArrayList<Book>) getArguments().getSerializable("bookarray");
list_pos = getArguments().getInt("index");
}
vp = (ViewPager) view.findViewById(R.id.viewpager);
adapterViewPager = new MyPagerAdapter(getFragmentManager());
vp.setAdapter(adapterViewPager);
Your fragment has not been destroyed and therefore when it is brought back, onCreateView is not being called. Instead override setUserVisibleHint.
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// This is true when your fragment is visible, write code to populate view here
} else {
// This is true when your fragment is hidden.
}
}
The solution i found is to change the Fragment Manager
adapterViewPager = new MyPagerAdapter(getFragmentManager());
to
adapterViewPager = new MyPagerAdapter(getChildFragmentManager());

How to use ParseObjects with a RecyclerView?

I am attempting to pull data from my parse server and display an image and text within a RecyclerView of CardViews. I have encountered a few issues, some of which may not have been corrected appropriately, so please feel free to correct any novice code you find below outside of my two current issues. Finally my two issues are.
The data does not display initially. I have 3 tabs in a ViewPager and I have to swipe over twice in order for it to display. If I'm on tab 1 the data doesn't appear until I swipe to tab 3 and return to tab 1, and vice versa. Because there isn't a tab 4, tab 2 never displays.
The second issue I am currently faced with is that at times the data will not match up. It will have the picture from one row matched with the description from another entity.
Below is my MusicFragment.java
public class MusicFragment extends Fragment {
private ArrayList<String> titles = new ArrayList<>();
private ArrayList<Bitmap> bitmaps = new ArrayList<>();
private ArrayList<String> descriptions = new ArrayList<>();
private boolean notComplete = true;
public MusicFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
RecyclerView musicRecycler = (RecyclerView)inflater.inflate(
R.layout.fragment_music, container, false);
if (notComplete) {
// Get the MusicFragImages class as a reference.
ParseQuery<ParseObject> query = new ParseQuery<>("MusicFragImages");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
for (ParseObject object : objects) {
String description = (String) object.get("description");
ParseFile file = (ParseFile) object.get("image");
String title = (String) object.get("title");
titles.add(title);
descriptions.add(description);
file.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (e == null && data != null) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
bitmaps.add(bitmap);
}
}
});
}
} else {
Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
notComplete = false;
}
// Create captioned images and registers it to the adapter.
CaptionedImagesAdapter adapter = new CaptionedImagesAdapter(titles, bitmaps, descriptions);
musicRecycler.setAdapter(adapter);
// Set up the layout.
GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 1);
musicRecycler.setLayoutManager(layoutManager);
adapter.setListener(new CaptionedImagesAdapter.Listener() {
public void onClick(int position) {
Intent intent;
switch (position) {
case 0:
intent = new Intent(getActivity(), AudioActivity.class);
getActivity().startActivity(intent);
break;
case 1:
intent = new Intent(getActivity(), VideoActivity.class);
getActivity().startActivity(intent);
break;
}
}
});
return musicRecycler;
}
}
Additionally, here is my CaptionedImagesAdapter
class CaptionedImagesAdapter extends
RecyclerView.Adapter<CaptionedImagesAdapter.ViewHolder> {
private final ArrayList<String> captions;
private final ArrayList<Bitmap> bitmaps;
private final ArrayList<String> descriptions;
private Listener listener;
interface Listener {
void onClick(int position);
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final CardView cardView;
public ViewHolder(CardView v) {
super(v);
cardView = v;
}
}
public CaptionedImagesAdapter(ArrayList<String> captions, ArrayList<Bitmap> bitmaps, ArrayList<String> descriptions) {
this.captions = captions;
this.bitmaps = bitmaps;
this.descriptions = descriptions;
}
#Override
public int getItemCount() {
return captions.size();
}
public void setListener(Listener listener) {
this.listener = listener;
}
#Override
public CaptionedImagesAdapter.ViewHolder onCreateViewHolder(
ViewGroup parent, int viewType) {
CardView cv = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.card_selection_2, parent, false);
return new ViewHolder(cv);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final int index = position;
// Creates a CardView
CardView cardView = holder.cardView;
ImageView imageView = cardView.findViewById(R.id.type_image);
imageView.setImageBitmap(bitmaps.get(index));
imageView.setContentDescription(descriptions.get(index));
// Populate the caption.
TextView textView = cardView.findViewById(R.id.type_text);
textView.setText(captions.get(index));
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
if (listener != null)
listener.onClick(index);
}
});
}
}
FOR REFERENCE...... if needed MainActivity.java is below
public class MainActivity extends AppCompatActivity {
// Variables for the audio player.
public static MediaPlayer mediaPlayer;
public static int albumId;
public static int currentSong = -1;
public static boolean isPlaying = false;
private static int[] songs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Attach the SectionsPageAdapter to the ViewPager
SectionsPageAdapter pagerAdapter = new SectionsPageAdapter(getSupportFragmentManager());
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(pagerAdapter);
int currentTab = 0;
pager.setCurrentItem(currentTab);
// Attach the ViewPager to the TabLayout
TabLayout tabLayout = (TabLayout)findViewById(R.id.tabs);
tabLayout.setupWithViewPager(pager);
// Starts the player.
player();
}
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the app bar.
getMenuInflater().inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent;
switch (item.getItemId()) {
case R.id.action_contact:
intent = new Intent(MainActivity.this, ContactActivity.class);
startActivity(intent);
return true;
case R.id.action_cart:
intent = new Intent(this, CartActivity.class);
startActivity(intent);
return true;
case R.id.action_member:
intent = new Intent(this, ProfileActivity.class);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private class SectionsPageAdapter extends FragmentPagerAdapter {
public SectionsPageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 3;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new MusicFragment();
case 1:
return new ArtFragment();
case 2:
return new FashionFragment();
}
return null;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getResources().getText(R.string.title_music);
case 1:
return getResources().getText(R.string.title_art);
case 2:
return getResources().getText(R.string.title_fashion);
}
return null;
}
}
private void player() {
/*Create a background thread that will automatically advance to
* the next song, as long as there is a next song.*/
// Get the songs.
songs = AudioData.audio[albumId].getSongs();
final Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
if (isPlaying) {
if (!(mediaPlayer.isPlaying()) && currentSong < songs.length - 1) {
mediaPlayer.stop();
mediaPlayer.reset();
currentSong++;
mediaPlayer = MediaPlayer.create(MainActivity.this, songs[currentSong]);
mediaPlayer.start();
isPlaying = true;
}
//Set the flag to false at the end of the album.
if (currentSong == songs.length) {
isPlaying = false;
}
}
handler.postDelayed(this, 1000);
}
});
}
#Override
public void onBackPressed() {
super.onBackPressed();
finishAffinity();
}
}
Thanks again to Harikumar for correcting the first issue. I ended up correcting the second issue with the code below. It was within the enhance for loop.
for (ParseObject object : objects) {
String description = (String) object.get("description");
ParseFile file = (ParseFile) object.get("image");
String title = (String) object.get("title");
Bitmap bitmap;
titles.add(title);
descriptions.add(description);
byte[] data;
try {
data = file.getData();
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
bitmaps.add(bitmap);
adapter.notifyDataSetChanged(); //notify your adapter that data has changed
} catch (ParseException pe) {
Toast.makeText(getContext(), pe.getMessage(), Toast.LENGTH_SHORT).show();
}
}
Data will be updated if you notify your adapter CaptionedImagesAdapter. Try modifying the code to:
public class MusicFragment extends Fragment {
private ArrayList<String> titles = new ArrayList<>();
private ArrayList<Bitmap> bitmaps = new ArrayList<>();
private ArrayList<String> descriptions = new ArrayList<>();
private CaptionedImagesAdapter adapter;
private boolean notComplete = true;
public MusicFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
RecyclerView musicRecycler = (RecyclerView)inflater.inflate(
R.layout.fragment_music, container, false);
GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 1);
musicRecycler.setLayoutManager(layoutManager);
adapter = new CaptionedImagesAdapter(titles, bitmaps, descriptions);
musicRecycler.setAdapter(adapter);
if (notComplete) {
// Get the MusicFragImages class as a reference.
ParseQuery<ParseObject> query = new ParseQuery<>("MusicFragImages");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
for (ParseObject object : objects) {
String description = (String) object.get("description");
ParseFile file = (ParseFile) object.get("image");
String title = (String) object.get("title");
titles.add(title);
descriptions.add(description);
file.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (e == null && data != null) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
bitmaps.add(bitmap);
adapter.notifyDataSetChanged(); //notify your adapter that data has changed
}
}
});
}
} else {
Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
notComplete = false;
}
adapter.setListener(new CaptionedImagesAdapter.Listener() {
public void onClick(int position) {
Intent intent;
switch (position) {
case 0:
intent = new Intent(getActivity(), AudioActivity.class);
getActivity().startActivity(intent);
break;
case 1:
intent = new Intent(getActivity(), VideoActivity.class);
getActivity().startActivity(intent);
break;
}
}
});
return musicRecycler;
}
}
Here is a small optimization for your 2nd solution: update notifyDataSetChanged() only once after the for loop (put it just outside the for loop). This is better in terms of performance.

List item won't stay selected despite setting necessary properties

I'm trying to get the selected item within my list view to stay highlighted when I select it but for some reason it won't do that the moment the selected item is not in view. E.g. When I select Item 4, that list item does get highlighted but when I scroll through the list it doesn't stay highlighted and then other items randomly become highlighted. Even when I return to Item 4, that item is no longer highlighted. I really don't understand why this is happening. What can be done to resolve this issue? All relevant help would be appreciated.
fragment_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragmentmain">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="false"
android:layout_centerHorizontal="true"
android:choiceMode="singleChoice"/>
</LinearLayout>
MainListAdapter.java
public class MainListAdapter extends BaseAdapter implements Filterable {
private List<Main> mData;
private List<Main> mFilteredData;
private LayoutInflater mInflater;
private ItemFilter mFilter;
public MainListAdapter (List<Main> data, Context context) {
mData = data;
mFilteredData = new ArrayList(mData);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return mFilteredData.size();
}
#Override
public Main getItem(int position) {
return mFilteredData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.item);
holder.description = (TextView) convertView.findViewById(R.id.item_description);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Main main = getItem(position);
holder.title.setText(main.getContinent());
holder.description.setText(main.getDescription());
if (main.isSelected()) {
convertView.setBackgroundColor(Color.parseColor("#1C3F96"));
holder.title.setTextColor(Color.parseColor("#FFFFFF"));
holder.description.setTextColor(Color.parseColor("#FFFFFF"));
} else {
convertView.setBackgroundColor(Color.TRANSPARENT);
holder.title.setTextColor(Color.parseColor("#FFFFFF"));
holder.description.setTextColor(Color.parseColor("#B5B5B5"));
}
holder.title.setText(mFilteredData.get(position).getContinent());
holder.description.setText(mFilteredData.get(position).getDescription());
return convertView;
}
#Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ItemFilter();
}
return mFilter;
}
/**
* View holder
*/
static class ViewHolder {
private TextView title;
private TextView description;
}
/**
* Filter for filtering list items
*/
/**
* <p>An array filter constrains the content of the array adapter with
* a prefix. Each item that does not start with the supplied prefix
* is removed from the list.</p>
*/
private class ItemFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (TextUtils.isEmpty(constraint)) {
results.count = mData.size();
results.values = new ArrayList(mData);
} else {
//Create a new list to filter on
List<Main> resultList = new ArrayList<Main>();
for (Main str : mData) {
if (str.getContinent().toLowerCase().contains(constraint.toString().toLowerCase())) {
resultList.add(str);
}
}
results.count = resultList.size();
results.values = resultList;
}
return results;
}
/**
* Runs on ui thread
* #param constraint the constraint used for the result
* #param results the results to display
*/
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count == 0) {
mFilteredData.clear();
notifyDataSetInvalidated();
} else {
mFilteredData = (ArrayList<Main>)results.values;
notifyDataSetChanged();
}
}
}
}
Main.java (in the "data" package)
public class Main {
public Main(){}
private String continent;
private String description;
private boolean selected;
public String getContinent(){
return continent;
}
public void setContinent(String continent){
this.continent = continent;
}
public String getDescription(){
return description;
}
public void setDescription(String description){
this.description = description;
}
private int _id;
public void getID(int _id){
this._id = _id;
}
public int setID(){
return _id;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
MainActivity.java
public class MainActivity extends ActionBarActivity {
private boolean mTwoPane;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentMain newFragment = new FragmentMain();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.master_container, newFragment);
transaction.commit();
if (findViewById(R.id.detail_container) != null) {
mTwoPane = true;
}
}
#Override
protected void onNewIntent(Intent intent) {
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
//use the query to search your data somehow
}
}
}
FragmentMain.java
public class FragmentMain extends ListFragment implements SearchView.OnQueryTextListener {
private MainListAdapter mAdapter;
public FragmentMain() {
// Required empty constructor
}
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
*/
public boolean mTwoPane;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
//Tell the system to call onCreateOptionsMenu
setHasOptionsMenu(true);
initialize(view);
return view;
}
List<Main> list = new ArrayList<>();
private void initialize(View view) {
String[] items = getActivity().getResources().getStringArray(R.array.items);
String[] itemDescriptions = getActivity().getResources().getStringArray(R.array.item_descriptions);
for (int n = 0; n < items.length; n++){
Main world = new Main();
world.setID();
world.setContinent(items[n]);
world.setDescription(itemDescriptions[n]);
list.add(world);
}
mAdapter = new MainListAdapter(list, getActivity());
setListAdapter(mAdapter);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
View v = getView();
mTwoPane = getActivity().findViewById(R.id.detail_container) != null;
ListView lv = (ListView)v.findViewById(android.R.id.list);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// get the adapter, then get the name from the adapter at that position
MainListAdapter adapter = (MainListAdapter) parent.getAdapter();
Main main = adapter.getItem(position);
if (mTwoPane) {
setItemNormal();
View rowView = view;
setItemSelected(rowView);
Fragment newFragment;
switch (position) {
case 0:
newFragment = new Fragment0();
break;
case 1:
newFragment = new Fragment1();
break;
case 2:
newFragment = new Fragment2();
break;
case 3:
newFragment = new Fragment3();
break;
case 4:
newFragment = new Fragment4();
break;
case 5:
newFragment = new Fragment5();
break;
case 6:
newFragment = new Fragment6();
break;
case 7:
newFragment = new Fragment7();
break;
case 8:
newFragment = new Fragment8();
break;
case 9:
newFragment = new Fragment9();
break;
case 10:
newFragment = new Fragment10();
break;
case 11:
newFragment = new Fragment11();
break;
case 12:
newFragment = new Fragment12();
break;
case 13:
newFragment = new Fragment13();
break;
case 14:
newFragment = new Fragment14();
break;
case 15:
newFragment = new Fragment15();
break;
case 16:
newFragment = new Fragment16();
break;
case 17:
newFragment = new Fragment17();
break;
case 18:
newFragment = new Fragment18();
break;
case 19:
newFragment = new Fragment19();
break;
case 20:
newFragment = new Fragment20();
break;
default:
newFragment = new Fragment0();
}
MainActivity activity = (MainActivity) view.getContext();
FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.fade_out, R.anim.fade_in);
transaction.replace(R.id.detail_container, newFragment);
transaction.commit();
} else {
Intent intent;
if (main.equals(view.getResources().getString(R.string.item0))) {
intent = new Intent(getActivity(), Activity0.class);
} else if (main.equals(view.getResources().getString(R.string.item1))) {
intent = new Intent(getActivity(), Activity1.class);
} else if (main.equals(view.getResources().getString(R.string.item2))) {
intent = new Intent(getActivity(), Activity2.class);
} else if (main.equals(view.getResources().getString(R.string.item3))) {
intent = new Intent(getActivity(), Activity3.class);
} else if (main.equals(view.getResources().getString(R.string.item4))) {
intent = new Intent(getActivity(), Activity4.class);
} else if (main.equals(view.getResources().getString(R.string.item5))) {
intent = new Intent(getActivity(), Activity5.class);
} else if (main.equals(view.getResources().getString(R.string.item6))) {
intent = new Intent(getActivity(), Activity6.class);
} else if (main.equals(view.getResources().getString(R.string.item7))) {
intent = new Intent(getActivity(), Activity7.class);
} else if (main.equals(view.getResources().getString(R.string.item8))) {
intent = new Intent(getActivity(), Activity8.class);
} else if (main.equals(view.getResources().getString(R.string.item9))) {
intent = new Intent(getActivity(), Activity9.class);
} else if (main.equals(view.getResources().getString(R.string.item10))) {
intent = new Intent(getActivity(), Activity10.class);
} else if (main.equals(view.getResources().getString(R.string.item11))) {
intent = new Intent(getActivity(), Activity11.class);
} else if (main.equals(view.getResources().getString(R.string.item12))) {
intent = new Intent(getActivity(), Activity12.class);
} else if (main.equals(view.getResources().getString(R.string.item13))) {
intent = new Intent(getActivity(), Activity13.class);
} else if (main.equals(view.getResources().getString(R.string.item14))) {
intent = new Intent(getActivity(), Activity14.class);
} else if (main.equals(view.getResources().getString(R.string.item15))) {
intent = new Intent(getActivity(), Activity15.class);
} else if (main.equals(view.getResources().getString(R.string.item16))) {
intent = new Intent(getActivity(), Activity16.class);
} else if (main.equals(view.getResources().getString(R.string.item17))) {
intent = new Intent(getActivity(), Activity17.class);
} else if (main.equals(view.getResources().getString(R.string.item18))) {
intent = new Intent(getActivity(), Activity18.class);
} else if (main.equals(view.getResources().getString(R.string.item19))) {
intent = new Intent(getActivity(), Activity19.class);
} else if (main.equals(view.getResources().getString(R.string.item20))) {
intent = new Intent(getActivity(), Activity20.class);
} else {
intent = new Intent(getActivity(), Activity0.class);
}
startActivity(intent);
}
}
public void setItemSelected(View view) {
View rowView = view;
view.setBackgroundColor(Color.parseColor("#1C3F96"));
TextView tv0 = (TextView) rowView.findViewById(R.id.item);
tv0.setTextColor(Color.parseColor("#FFFFFF"));
TextView tv1 = (TextView) rowView.findViewById(R.id.item_description);
tv1.setTextColor(Color.parseColor("#FFFFFF"));
}
public void setItemNormal() {
for (int i = 0; i < getListView().getChildCount(); i++) {
View v = getListView().getChildAt(i);
v.setBackgroundColor(Color.TRANSPARENT);
TextView tv0 = ((TextView) v.findViewById(R.id.item));
tv0.setTextColor(Color.WHITE);
TextView tv1 = ((TextView) v.findViewById(R.id.item_description));
tv1.setTextColor(Color.parseColor("#B5B5B5"));
}
}
});
super.onActivityCreated(savedInstanceState);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
MenuItem searchViewMenuItem = menu.findItem(R.id.action_search);
SearchView mSearchView = (SearchView) MenuItemCompat.getActionView(searchViewMenuItem);
int searchImgId0 = android.support.v7.appcompat.R.id.search_button;
ImageView v0 = (ImageView) mSearchView.findViewById(searchImgId0);
v0.setImageResource(R.drawable.ic_action_search_light);
int searchImgId1 = android.support.v7.appcompat.R.id.search_close_btn;
ImageView v1 = (ImageView) mSearchView.findViewById(searchImgId1);
v1.setImageResource(R.drawable.ic_action_content_clear_light);
super.onPrepareOptionsMenu(menu);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Set up search view
inflater.inflate(R.menu.menu_main, menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setIconifiedByDefault(true);
searchView.clearAnimation();
searchView.setOnQueryTextListener(this);
}
#Override
public boolean onQueryTextSubmit(String newText) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
mAdapter.getFilter().filter(newText);
return false;
}
}
list_item.xml
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:baselineAligned="false"
android:paddingStart="12dp"
android:paddingEnd="12dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:id="#+id/item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:textColor="?android:attr/textColorPrimary" />
<TextView android:id="#+id/item_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/item"
android:layout_alignStart="#id/item"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary" />
</RelativeLayout>
Updated screenshot 31/07/2015
Android ListView reuses its views while you scroll it. You need to store information about a selected item in an item object and check if it is selected inside getView.
Call setItemSelected if it is selected and setItemNormal otherwise. This way you will update the selected state of each item while you scrolling the list.
EDIT
#Override
public Main getItem(int position) {
return mFilteredData.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.item);
holder.description = (TextView) convertView.findViewById(R.id.item_description);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Main main = getItem(position);
holder.title.setText(main.getContinent());
holder.description.setText(main.getDescription());
if (main.isSelected()) {
convertView.setBackgroundColor(Color.parseColor("#1C3F96"));
holder.title.setTextColor(Color.parseColor("#FFFFFF"));
holder.description.setTextColor(Color.parseColor("#FFFFFF"));
} else {
convertView.setBackgroundColor(Color.TRANSPARENT);
holder.title.setTextColor(Color.parseColor("#FFFFFF"));
holder.description.setTextColor(Color.parseColor("#B5B5B5"));
}
return convertView;
}
Inside your onItemClick:
...
switch (position) {
case 0:
newFragment = new Fragment0();
break;
case 1:
newFragment = new Fragment1();
break;
// etc..
default:
newFragment = new Fragment0();
}

invalidateViews() and notifyDataSetChanged() doesnt work for me

i using ListView in fragment. I have one asynctask to download json data from remote server. I try refresh programmatically my displayed adapter/listview in onPostExecute function but it doesn't work for me.
My main activity with three fragments, three listview, three adapter and one async task.
public class ContactsActivity extends ActionBarActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
private static List<Item> BackList = new ArrayList<Item>();
private static List<Item> BackList2 = new ArrayList<Item>();
private static List<Item> BackList3 = new ArrayList<Item>();
private static ListView ListView;
private static Context activity;
public static String HASH;
private static final String[] timestamp = {"0"};
private static WeatherAdapter adapter;
private static int fragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.contacts);
Intent myIntent= getIntent();
HASH = myIntent.getStringExtra("HASH");
Log.d("Intent - contactActivity", HASH);
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
(new PrefetchData()).execute();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.contacts, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return PlaceholderFragment.newInstance(position + 1);
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
fragment = position;
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
}
public static Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static class PlaceholderFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
int index = getArguments().getInt(ARG_SECTION_NUMBER);
fragment = index;
activity = getActivity();
ListView listview1 = (ListView) rootView.findViewById(R.id.listView);
switch(fragment){
case 1:
adapter = new WeatherAdapter(activity, R.layout.listview_item_row, BackList);
listview1.setOnItemClickListener(new ListView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int i, long l) {
Intent rozmowa = new Intent(getActivity(), Incotalk.class);
rozmowa.putExtra("HASH", HASH);
startActivity(rozmowa);
}
});
break;
case 2:
adapter = new WeatherAdapter(activity, R.layout.listview_item_row2, BackList2);
break;
case 3:
adapter = new WeatherAdapter(activity, R.layout.listview_item_row3, BackList3);
break;
}
listview1.setAdapter(adapter);
ListView = listview1;
return rootView;
}
}
/**
* Async Task to make http call
*/
private class PrefetchData extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// before making http calls
}
#Override
protected Void doInBackground(Void... arg0) {
final String id = HASH;
final String url = "http://freshfrog.pl/projects/talk.php?user="+id+"&t=" + timestamp[0];
Log.d("BBB","start");
try {
String page = new Communicator().executeHttpGet(url);
JSONObject jsonObject = new JSONObject(page);
timestamp[0] = jsonObject.getString("t");
HASH = jsonObject.getJSONObject("s").getString("hash");
JSONArray oczekujacy = jsonObject.getJSONArray("m");
// wiadomosci
BackList.clear(); // czyści przed odświerzeniem
BackList2.clear();
BackList3.clear();
for (int i=oczekujacy.length()-1; i>0; i--) {
JSONObject actor = oczekujacy.getJSONObject(i);
String message = actor.getString("m");
String hash = actor.getString("n");
String t = actor.getString("t");
int l = BackList.size();
Boolean jest = false;
for(int j=0; j<l; j++){
Item item = BackList.get(j);
if(!item.isSection()){
ContactItem contactItem= (ContactItem) item;
if( (contactItem.hash).equals(hash) ){
jest = true;
break;
}
}
//Log.d("bbb", BackList.get(j).hash);
}
if(!jest && !hash.equals(id)) BackList.add(
new ContactItem(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher),
message,
hash));
}
// znajomi
BackList2.add(new SectionItem("Otrzymane zaproszenia"));
oczekujacy = jsonObject.getJSONObject("f").getJSONObject("p").getJSONArray("sending");
for (int i=0; i<oczekujacy.length(); i++) {
JSONObject actor = oczekujacy.getJSONObject(i);
String name = actor.getString("name");
String hash = actor.getString("hash");
String avatar = actor.getString("avatar");
BackList2.add(new ContactItem(getBitmapFromURL(avatar) , name, hash) );
}
// szukaj
BackList3.add(new SectionItem("Znajomi"));
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
while (phones.moveToNext())
{
String name= phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
BackList3.add(new ContactItem(
BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher),
name,
phoneNumber) );
}
} catch (Exception e) {
Log.d("BBB", e.toString());
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
/* gdy skończy */
adapter.notifyDataSetChanged();
ListView listview2 = (ListView) findViewById(R.id.listView);
listview2.invalidateViews();
//Toast.makeText(ContactsActivity.this, "coś przyszło", Toast.LENGTH_SHORT).show();
Log.d("BBB", "powinno sie odswieżyc");
new PrefetchData().execute();
}
}
}
My custom adapter
public class WeatherAdapter extends ArrayAdapter<Item> {
Context context;
int layoutResourceId;
List<Item> data = null;
private LayoutInflater vi;
public WeatherAdapter(Context context, int layoutResourceId, List<Item> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
WeatherHolder holder = null;
SectionHolder holder2 = null;
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
Item i = data.get(position);
if(row == null){
if(!i.isSection()){
row = inflater.inflate(layoutResourceId, parent, false);
holder = new WeatherHolder();
holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
row.setTag(holder);
ContactItem contactItem = (ContactItem)i;
holder.txtTitle.setText(contactItem.title);
holder.imgIcon.setImageBitmap(contactItem.icon);
}else{
row = inflater.inflate(R.layout.listview_header_row, parent, false);
holder2 = new SectionHolder();
holder2.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
row.setTag(holder2);
SectionItem sectionItem = (SectionItem)i;
holder2.txtTitle.setText(sectionItem.title);
}
}
else
{
if(!i.isSection()){
//holder = (WeatherHolder) row.getTag();
}else{
//holder2 = (SectionHolder) row.getTag();
}
}
return row;
}
public void update(List<Item> newlist) {
Log.d("bbb","aktualizacja listview");
data.clear();
data.addAll(newlist);
this.notifyDataSetChanged();
}
#Override
public void notifyDataSetChanged() // Create this function in your adapter class
{
//notifySetDataChanged()
super.notifyDataSetChanged();
}
static class WeatherHolder
{
ImageView imgIcon;
TextView txtTitle;
}
static class SectionHolder
{
TextView txtTitle;
}
}
the part of the "if(row == null){" should only contain initializations of the views and the viewHolders.
it shouldn't contain any setting of data to the views.
after this part ( after the "else {...}" ) , you should update the views with the new data .
here's my fix to your code (looks ugly, but should work) :
...
int type=getViewType();
switch(type)
{
case 0:
if(row == null)
{
row = inflater.inflate(layoutResourceId, parent, false);
holder = new WeatherHolder();
holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
row.setTag(holder);
}
else
holder = (WeatherHolder) row.getTag();
ContactItem contactItem = (ContactItem)i;
holder.txtTitle.setText(contactItem.title);
holder.imgIcon.setImageBitmap(contactItem.icon);
break;
case 1:
if(row == null)
{
row = inflater.inflate(R.layout.listview_header_row, parent, false);
holder2 = new SectionHolder();
holder2.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
row.setTag(holder2);
}
else
holder2 = (SectionHolder) row.getTag();
SectionItem sectionItem = (SectionItem)i;
holder2.txtTitle.setText(sectionItem.title);
break;
}
return row;
...
... int getViewType(...) {... return i.isSection()? 1:0;}
... int getViewTypeCount(){return 2;}
btw, you should really watch the lecture "the world of listView" . they have great tips that will make your code much better.
for example, you can use getViewTypeCount , getViewType, getItem, as shown on the API .
to view your code i see that you have started your async execution again on postExcecute
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
/* gdy skończy */
adapter.notifyDataSetChanged();
ListView listview2 = (ListView) findViewById(R.id.listView);
listview2.invalidateViews();
//Toast.makeText(ContactsActivity.this, "coś przyszło", Toast.LENGTH_SHORT).show();
Log.d("BBB", "powinno sie odswieżyc");
new PrefetchData().execute();
}
also clearing data inside your doBackground
To get changes on your data you should not clear your data just get updates records and notify your adapeter
try to change the method data.addAll(newlist) by using addall(newlist, data);
inside addall method add one by one the list of element. this way it should work.
i had the same problem and i correct it the way i explained.

ViewPager, FragmentStatePagerAdapter, ListFragment separate list data for each Fragment

I have a ViewPager with a dynamic number of pages in it. Each of these pages needs to read from a db and display the dataset for that page.
I compare the currently selected pages title with the first value in the db "username" to check if the data is relevant for that page.
My fragments though dont display the data correctly. Im trying to set an arrayAdapter in the onCreateView, but its not called on the creation of each fragment. In my test case, I have three fragments, user1, user2, user3. onCreateView is called on user1 originally, then is only called again when I swipe back to user2, and never again for user1 or user3.
I need to be able to set the arrayAdapter for each fragment specifically because each one will have a different array of values to display.
PagerAdapter
public class ExamplePagerAdapter extends FragmentStatePagerAdapter implements TitleProvider{
private Map<Integer, UserFragment> mPageReferenceMap = new HashMap<Integer, UserFragment>();
public ExamplePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return user;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new UserFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public String getTitle(int pos) {
return "#"+users[pos].getName();
}
#Override
public void destroyItem(View container, int position, Object object) {
mPageReferenceMap.remove(Integer.valueOf(position));
}
}
UserFragment
public class UserFragment extends ListFragment {
Context ctx;
View v;
Button mAddEntry;
static int p;
static ArrayList<String> entryArray;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ctx = container.getContext();
if (v != null)
return v;
v = inflater.inflate(R.layout.user_fragment, container, false);
mAddEntry = (Button) v.findViewById(R.id.entry_b);
mAddEntry.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Bundle b = new Bundle();
b.putInt("pos", p);
Intent mi = new Intent(v.getContext(), EntryAdd.class);
mi.putExtras(b);
startActivity(mi);
}
});
updateUserFrag();
return v;
}
public void updateUserFrag () {
entryArray = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
final DBAdapter db = new DBAdapter(ctx);
db.open();
Cursor c = db.getAllEntries();
try {
while (c.moveToNext()) {
if (c.getString(0).equals(MainActivity.users[p].getName())) {
sb.append(c.getString(1));
entryArray.add(sb.toString());
}
}
} catch (Exception e) {}
c.close();
db.close();
ArrayAdapter<String> a = new ArrayAdapter<String>(ctx, android.R.layout.simple_list_item_1, entryArray);
setListAdapter(a);
}
}
Basically, I just need a method I can use to give each fragment its data when its created. onCreateView() doesnt get called for each fragment, so thats no use for me.
UPDATE
I think I've almost got it, but I cant figure out this last part. Im using TitlePageIndicators onPageSelected method to send data to my fragment handler.
TitlePageIndicator indicator = (TitlePageIndicator)findViewById(R.id.indicator);
indicator.setViewPager(pager, 0);
indicator.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
Message msg = UserFragment.handy.obtainMessage();
Bundle b = new Bundle();
b.putInt("m", 0);
b.putInt("p", position);
b.putStringArrayList("e", updateUserFrag(position));
msg.setData(b);
UserFragment.handy.handleMessage(msg);
}
Handler
static Handler handy = new Handler() {
public void handleMessage(Message msg) {
int p = msg.getData().getInt("p");
int m = msg.getData().getInt("m");
ArrayList<String> e = msg.getData().getStringArrayList("e");
switch (m) {
case 0:
Log.d("HANDLER", Integer.toString(p));
for (int i=0;i<e.size();i++) {
//Log.d("ENTRY", e.get(i));
}
break;
}
}
};
The problem is that by the time the handler is called, the Arrayadapter has already been set, and I can find a way to trigger a refresh of that data.
#Override
public void onPageSelected(int position) {
Message msg = UserFragment.handy.obtainMessage();
Bundle b = new Bundle();
b.putInt("m", 0);
b.putInt("p", position);
b.putStringArrayList("e", updateUserFrag(position));
msg.setData(b);
UserFragment.handy.handleMessage(msg);
}
public ArrayList<String> updateUserFrag (int p) {
entryArray = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
DBAdapter db = new DBAdapter(this);
db.open();
Cursor c = db.getAllEntries();
try {
while (c.moveToNext()) {
if (c.getString(0).equals(users[p].getName())) {
sb.append(c.getString(1));
entryArray.add(sb.toString());
}
}
} catch (Exception e) {}
c.close();
db.close();
return entryArray;
}
UserFragment
public class UserFragment extends ListFragment {
Context ctx;
View v;
Button mAddEntry;
static int p;
static ArrayList<String> entryArray;
static ArrayAdapter<String> a;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ctx = container.getContext();
if (v != null)
return v;
v = inflater.inflate(R.layout.user_fragment, container, false);
mAddEntry = (Button) v.findViewById(R.id.entry_b);
mAddEntry.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Bundle b = new Bundle();
b.putInt("pos", p);
Intent mi = new Intent(v.getContext(), EntryAdd.class);
mi.putExtras(b);
startActivity(mi);
}
});
updateUserFrag(p);
return v;
}
public void updateUserFrag (int p) {
entryArray = new ArrayList<String>();
a = new ArrayAdapter<String>(ctx, android.R.layout.simple_list_item_1, entryArray);
setListAdapter(a);
}
static Handler handy = new Handler() {
public void handleMessage(Message msg) {
int p = msg.getData().getInt("p");
int m = msg.getData().getInt("m");
ArrayList<String> e = msg.getData().getStringArrayList("e");
switch (m) {
case 0:
Log.d("HANDLER", Integer.toString(p));
entryArray.clear();
for (int i=0;i<e.size();i++) {
entryArray.add(e.get(i));
}
a.notifyDataSetChanged();
break;
}
}
};
}

Categories

Resources