Remove reloading of list fragments when back button is pressed - java

I created a Tabbed Activity where all the list fragments are pro grammatically created when the activity is first opened as you can see based on previously saved data.
public class CcSongBook extends ActionBarActivity implements TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
SharedPreferences vSettings;
SharedPreferences.Editor localEditor;
public SongBookSQLite db = new SongBookSQLite(this, SongBookDatabase.DATABASE, null, SongBookDatabase.VERSION);
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sb_book);
vSettings = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
localEditor = PreferenceManager.getDefaultSharedPreferences(this).edit();
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(2);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(this.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));
}
}
#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 {
String[] songbooks = TextUtils.split(vSettings.getString("js_vsb_sbcodes", "NA"), ",");
String[] songbookno = TextUtils.split(vSettings.getString("js_vsb_sbnos", "NA"), ",");
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return songbooks.length-1;
}
#Override
public CharSequence getPageTitle(int position) {
return songbooks[position];
}
public Fragment getItem(int position) {
Bundle data = new Bundle();
data.putInt("songbook", Integer.parseInt(songbookno[position]));
SongBookList sblist = new SongBookList();
sblist.setArguments(data);
return sblist;
}
}
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.sb_fragment, container, false);
return rootView;
}
}
}
then in my other class which is used in list fragments I am basically reading some specific values from my sqlite database based on the bundle data passed on from the base activity:
public class SongBookList extends ListFragment implements LoaderCallbacks<Cursor> {
public SongBookSQLite db;
private String[] My_Text, My_Texti, My_Textii;
List<SongItem> mylist;
ArrayAdapter<String> listAdapter;
SimpleCursorAdapter mCursorAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
db = new SongBookSQLite(getActivity().getBaseContext(), SongBookDatabase.DATABASE, null, SongBookDatabase.VERSION);
Bundle data = this.getArguments();
int curr_songbook = data.getInt("songbook", 1);
mylist = db.getAllSongs(curr_songbook);
List<String> listSongid = new ArrayList<String>();
List<String> listTitle = new ArrayList<String>();
List<String> listContent = new ArrayList<String>();
for (int i = 0; i < mylist.size(); i++) {
listSongid.add(i, Integer.toString(mylist.get(i).getSongid()));
listTitle.add(i, mylist.get(i).getTitle());
listContent.add(i, mylist.get(i).getContent());
}
My_Text = listSongid.toArray(new String[listSongid.size()]);
for (String string : My_Text) { System.out.println(string); }
My_Texti = listTitle.toArray(new String[listTitle.size()]);
for (String stringi : My_Texti) { System.out.println(stringi);}
My_Textii = listContent.toArray(new String[listContent.size()]);
for (String stringii : My_Textii) { System.out.println(stringii); }
setListAdapter(new CustomSongList(getActivity(), My_Text, My_Texti, My_Textii));
return super.onCreateView(inflater, container, savedInstanceState);
}
public void onStart() {
super.onStart();
getListView().setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent myIntent = new Intent(getActivity().getApplicationContext(), SongBookView.class);
Uri data = Uri.withAppendedPath(SongBookProvider.CONTENT_URI, String.valueOf(id+1));
myIntent.setData(data);
startActivity(myIntent);
}
});
}
public Loader<Cursor> onCreateLoader(int arg0, Bundle data) {
Uri uri = SongBookProvider.CONTENT_URI;
return new CursorLoader(getContext(), uri, null, null, new String[]{data.getString("query")}, null);
}
public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
this.mCursorAdapter.swapCursor(c);
}
public void onLoaderReset(Loader<Cursor> loader) {
}
Now when a list item is clicked on any list fragment it opens up in a new activity which is as below:
public class SongBookView extends ActionBarActivity {
TextView mSongCont;
Cursor cursor;
public Uri mUri;
SongBookSQLite db;
SharedPreferences vSettings;
SharedPreferences.Editor localEditor;
String VSB_SETTINGS, FONT_SIZE, CURRENT_SONG;
public int CurrSong, FontSize;
ListView StanzasList;
SongItem currentSong;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.song_view);
db = new SongBookSQLite(this, SongBookDatabase.DATABASE, null, SongBookDatabase.VERSION);
StanzasList =(ListView)findViewById(R.id.stanzalist);
vSettings = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
localEditor = PreferenceManager.getDefaultSharedPreferences(this).edit();
changeStatusBarColor();
Long rated_me_not = vSettings.getLong("js_vsb_rated_me_not", 0);
Long time_used = (System.currentTimeMillis() - rated_me_not) / 1000;
if (!PreferenceManager.getDefaultSharedPreferences(this).getBoolean("js_vsb_rate_me", false)) {
if (time_used > 18000 ) {
rateMePlease();
}
}
FontSize = PreferenceManager.getDefaultSharedPreferences(this).getInt("js_vsb_font_size", 15);
mUri = getIntent().getData();
CurrSong = Integer.parseInt(mUri.toString().replaceAll("\\D+", ""));
openCurrentSong();
}
public void openCurrentSong(){
localEditor.putInt("js_vsb_curr_song", CurrSong).commit();
currentSong = db.readSong(CurrSong);
setTitle(currentSong.getTitle());
String[] Stanzas = TextUtils.split(currentSong.getContent(), "`");
CustomSongView adapter = new CustomSongView(this, Stanzas);
StanzasList.setAdapter(adapter);
}
#Override
public void onBackPressed() {
Intent intent = new Intent(this, CcSongBook.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
}
The main question here is how do i prevent the main activity from reloading itself all over again because it is happening.

I have already seen when the back button is pressed its like a new intent is initiated. How about you removed the line:
Intent intent = new Intent(this, CcSongBook.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
from the method onBackPressed()

Actually removing the lines below did solve my problem
Intent intent = new Intent(this, CcSongBook.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Related

How to update listview in Fragment with custom adapter

I am giving product id with barcode scanner. I can add product to listView but when i try to increase or decrease amount of the product. It doesn't update UI. I used Toast message to see weather list is updated, it updates list but doesn't update UI
I have tried to use runOnUiThread() but i couldn't find any solution. How to update UI can you please help me
custom_lisView_row
BaseActivity which keeps MainFragment on it
public class BaseActivity extends AppCompatActivity {
public static final String MAIN_FRAGMENT = "mainFragment";
public static final String PRODUCTS = "products";
FragmentManager fragmentManager;
Dialog dialog ;
public static ArrayList<MyProduct> myProductList = new ArrayList<>();
public static MyTablet myTablet = new MyTablet();
Activity mActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
//Initialize fragment manager
fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.fl_BaseActivity, new MainFragment()).commit();
//Create database
mDatabase = FirebaseDatabase.getInstance().getReference();
dialog = new Dialog(this);
//Runs when i enter product id
initScanner();
}
public void updateMyProductList(MyProduct myProduct){
for(int i= 0 ; i< myProductList.size() ; i++ ){
MyProduct temp = myProductList.get(i);
if (temp.getId().equals(myProduct.getId())) {
temp.setAmount(temp.getAmount() + myProduct.getAmount());
myProductList.set(i, temp);
return;
}
}
myProductList.add(myProduct);
updateMainFragment();
}
private void initScanner() {
mDatabase.child(PRODUCTS).child(finalData).get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
MyProduct myProduct = task.getResult().getValue(MyProduct.class);
myProduct.setAmount(1);
dialog.setContentView(R.layout.custom_product_dialog);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.setCancelable(false);
TextView tv_addBasket_product_dialog = dialog.findViewById(R.id.tv_addBasket_product_dialog);
tv_addBasket_product_dialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
updateMyProductList(myProduct);
dialog.dismiss();
}
});
dialog.show();
}
};
}
public void updateMainFragment() {
if (isExist(MAIN_FRAGMENT)) {
Fragment fragment = findFragment(MAIN_FRAGMENT);
((MainFragment) fragment).updateMyList();
}
}
//Add fragments to BaseActivity
public void addFragments(Fragment fragment, String tag) {
fragmentManager.beginTransaction().add(R.id.fl_BaseActivity, fragment, tag).commit();
}
//Replace fragments to BaseActivity
public void replaceFragments(Fragment fragment, String tag) {
fragmentManager.beginTransaction().replace(R.id.fl_BaseActivity, fragment, tag).commit();
}
//Remove fragment from BaseActivity
public void removeFragment(String tag) {
Fragment fragmentB = fragmentManager.findFragmentByTag(tag);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (fragmentB != null) {
fragmentTransaction.remove(fragmentB);
fragmentTransaction.commit();
}
}
// finds fragment and returns it
// It may return null first check fragment is exist. use isExist() method
public Fragment findFragment(String tag) {
Fragment fragment = fragmentManager.findFragmentByTag(tag);
return fragment;
}
//Check fragment exist in BaseActivity
public boolean isExist(String tag) {
Fragment fragmentB = fragmentManager.findFragmentByTag(tag);
if (fragmentB != null) {
return true;
}
return false;
}
}
MainFragment
public class MainFragment extends Fragment {
ListView lv_MainFragment;
public MyProductListAdapter myListAdapter;
public static ArrayList<MyProduct> myProductList;
Activity mActivity;
#Override
public void onAttach(Context context) {
super.onAttach(context);
mActivity = getActivity();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myProductList = BaseActivity.myProductList;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
lv_MainFragment = view.findViewById(R.id.lv_MainFragment);
myListAdapter = new MyProductListAdapter(mActivity.getApplicationContext(), R.layout.custom_product_list_row, myProductList);
lv_MainFragment.setAdapter(myListAdapter);
return view;
}
public void updateMyList() {
myProductList = BaseActivity.myProductList;
myListAdapter.notifyDataSetChanged();
}
}
MyProductListAdapter
public class MyProductListAdapter extends ArrayAdapter<MyProduct> {
private Context mContext;
private ArrayList<MyProduct> list;
AppCompatButton acb_DecreaseAmount_productListRow, acb_IncreaseAmount_productListRow;
public MyProductListAdapter(Context context, int resource, ArrayList<MyProduct> objects) {
super(context, resource, objects);
this.mContext = context;
this.list = objects;
}
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.custom_product_list_row, parent, false);
tv_ProductAmount_productListRow = view.findViewById(R.id.tv_ProductAmount_productListRow);
acb_DecreaseAmount_productListRow = view.findViewById(R.id.acb_DecreaseAmount_productListRow);
acb_IncreaseAmount_productListRow = view.findViewById(R.id.acb_IncreaseAmount_productListRow);
tv_ProductAmount_productListRow.setText(String.valueOf(list.get(position).getAmount()));
acb_IncreaseAmount_productListRow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
double productPrice = list.get(position).getPrice();
int productAmount = list.get(position).getAmount();
productAmount++;
list.get(position).setAmount(productAmount);
Toast.makeText(mContext, String.valueOf(productAmount), Toast.LENGTH_SHORT).show();
tv_ProductAmount_productListRow.setText(String.valueOf(list.get(position).getAmount()));
}
});
acb_DecreaseAmount_productListRow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int productAmount = list.get(position).getAmount();
if (productAmount > 1) {
double productPrice = list.get(position).getPrice();
productAmount--;
list.get(position).setAmount(productAmount);
Toast.makeText(mContext, String.valueOf(productAmount), Toast.LENGTH_SHORT).show();
tv_ProductAmount_productListRow.setText(String.valueOf(list.get(position).getAmount()));
}
}
});
}
return view;
}
}
Hej Metehan,
your use case sounds perfect for a RecyclerView with a ListAdapter. You just submit a new list of products to the adapter and it will handle the updating and notifying for you.

pass value from activity to fragment using bundle in tabbed activity

I am a java-illiterate, and still trying to develop a app for my personal use.
I have started with android-studio's "Tabbed-Activity", and mostly unaltered except a fragment and a bundle in MainActivity.
Here are my codes:
MainActivity
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//FloatingActionButton fab = findViewById(R.id.fab);
Bundle bundle = new Bundle();
bundle.putDouble("loclat", 25.4358);
bundle.putDouble("loclang",81.8463);
Fragment SunFragment = new SunFragment();
SunFragment.setArguments(bundle);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
}
SectionsPagerAdapter
public class SectionsPagerAdapter extends FragmentPagerAdapter {
#StringRes
private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2, R.string.tab_text_3};
private final Context mContext;
public SectionsPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
//return PlaceholderFragment.newInstance(position + 1);
switch (position) {
case 0:
return new SunFragment();
//return PlaceholderFragment.newInstance(pos + 5);
case 1:
return PlaceholderFragment.newInstance(1);
//return SecondFragment.newInstance();
//return PlaceholderFragment.newInstance(pos + 1);
default:
return PlaceholderFragment.newInstance(2);
}
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return mContext.getResources().getString(TAB_TITLES[position]);
}
#Override
public int getCount() {
// Show 2 total pages.
return 3;
}
}
And finally, The SunFragment, where I want my bundled data from MainActivity:
public class SunFragment extends Fragment {
List<SunSession> sunsList;
Typeface sunfont;
Double Dlat;
Double Dlang;
//to be called by the MainActivity
public SunFragment() {
// Required empty public constructor
}
private static final String KEY_LOCATION_NAME = "location_name";
public String TAG ="SunFragment";
public String location;//="No location name found";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retrieve location and camera position from saved instance state.
if (savedInstanceState != null) {
location = savedInstanceState.getCharSequence(KEY_LOCATION_NAME).toString();
System.out.println("OnCreate location "+location);
// Dlat = getArguments().getDouble("loclat");
//Dlang = getArguments().getDouble("loclang");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_sun, container, false);
//onSaveInstanceState(new Bundle());
if (getArguments() != null) {
Dlat = getArguments().getDouble("loclat");
Dlang = getArguments().getDouble("loclang");
} else {
Dlat=23.1;
Dlang=79.9864;
}
Log.e("Lat", Double.toString(Dlat));
I have followed this blog to make it, but no value is passed. Kindly help.
NB. This is a better described, and detailed question of my earlier question, which I understand, needs more code to be shown.
In your MainActivity, your sunFragment is unused. Remove this part:
/*Bundle bundle = new Bundle();
bundle.putDouble("loclat", 25.4358);
bundle.putDouble("loclang",81.8463);
Fragment SunFragment = new SunFragment();
SunFragment.setArguments(bundle);*/
You have to set bundle to fragment inside your SectionsPagerAdapter
case 0:
Bundle bundle = new Bundle();
bundle.putDouble("loclat", 25.4358);
bundle.putDouble("loclang",81.8463);
Fragment sunFragment = new SunFragment();
sunFragment.setArguments(bundle);
return sunFragment;
But if you need to set the bundle to fragment from MainActivity. Then use a callback in that purpose.
This way you can pass data from your mainActivity to fragment
MainActivity onCreate method
adapter = new Adapter(getChildFragmentManager());
SquadsTeamListFragment teamA =
SquadsTeamListFragment.newInstance(teamAData,teamBData
adapter.addFragment(teamA, teamAName);
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
use this adapter in your main activity
static class Adapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
Adapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position){
return mFragmentTitleList.get(position);
}
}
receive data to fragment (SquadsTeamListFragment .java)
public static SquadsTeamListFragment newInstance(String playerList, String
oppPlayerList) {
SquadsTeamListFragment fragment = new SquadsTeamListFragment();
Bundle args = new Bundle();
args.putString(ARG_TEAM_DATA, playerList);
args.putString(ARG_OPP_TEAM_DATA, oppPlayerList);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
playerList = getArguments().getString(ARG_TEAM_DATA);
oppPlayerList = getArguments().getString(ARG_OPP_TEAM_DATA);
}
}

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());

Where to place EventBus.getDefault().unregister in BaseAdapter

Friends, I've spent enough time to find an answer to my question(here and on android's site) But no luck.
Here is the logic:
From DialogFragment upon finishing putting user's data he clicks OK button:
import de.greenrobot.event.EventBus;
...
public class AddDialogFragment extends DialogFragment implements
DialogInterface.OnClickListener {
...
public void onClick(DialogInterface dialog, int which) {
StringBuilder date = new StringBuilder(today.getText().subSequence(0,
today.getText().length()));
date = (date.toString().equals(getString(R.string.today))) ? new StringBuilder("20150104") : date;
int weight = 89;
String[] bsi = rb.getSelectedItems();
String[] gsi = rg.getSelectedItems();
DatabaseManipulation dm = new DatabaseManipulation(getActivity());
dm.run(date, weight, bsi, gsi);
dm.destroy();
DialogDataModel toSend = new DialogDataModel(weight, date.toString(), bsi, gsi);
/*
Context activity = getActivity();
if (activity instanceof WDActivity)
((WDActivity) activity).updateListItemFragment();
*/
EventBus.getDefault().post(new UpdateItemEvent(toSend));
Log.d(LOG_TAG, "send event");
Toast.makeText(getActivity(), R.string.saved_data, Toast.LENGTH_LONG).show();
}
...
Event is successfully sent to Adapter class which is registered for receiving this event:
...
import de.greenrobot.event.EventBus;
public class ItemsAdapter extends BaseAdapter implements ListAdapter {
private static final String LOG_TAG = "Logs";
private ArrayList<DialogDataModel> list = new ArrayList<DialogDataModel>();
private Context activity;
public ItemsAdapter (ArrayList<DialogDataModel> list, Context context) {
this.list = list;
this.activity = context;
registerEventBus();
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int pos) {
return list.get(pos);
}
#Override
public long getItemId(int pos) {
return pos;
//just return 0 if your list items do not have an Id variable.
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.row_item, null);
}
DialogDataModel curData = list.get(position);
TextView itemDate = (TextView)view.findViewById(R.id.item_date);
itemDate.setText(curData.getDate());
TextView itemWeight = (TextView)view.findViewById(R.id.item_weight);
itemWeight.setText( Integer.toString(curData.getWeight()) );
TextView itemEvents = (TextView)view.findViewById(R.id.item_events);
itemEvents.setText(curData.getEventsShort());
//Handle buttons and add onClickListeners
ImageButton editBtn = (ImageButton)view.findViewById(R.id.item_edit_btn);
editBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (activity instanceof WDActivity)
((WDActivity) activity).AddNewData(v, list.get(position));
notifyDataSetChanged();
}
});
ImageButton deleteBtn = (ImageButton) view.findViewById(R.id.item_delete_btn);
deleteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String date = list.get(position).getDate();
DatabaseManipulation dm = new DatabaseManipulation(activity);
dm.deleteItem(date);
dm.destroy();
list.remove(position);
notifyDataSetChanged();
}
});
return view;
}
public void registerEventBus(){
if (!EventBus.getDefault().isRegistered(this)) EventBus.getDefault().register(this);
Log.d(LOG_TAG, "Registred from adapter");
}
public void unregisterEventBus(){
EventBus.getDefault().unregister(this);
}
public void onEventMainThread(UpdateItemEvent event) {
Log.d(LOG_TAG, "Event fired!");
list = DialogDataModel.replaceFieldsInArray(list,event.getModel());
notifyDataSetChanged();
}
}
After clicking OK in dialog window the user sees the list of items and the item he's updated is up to date. Without this logic he sees the old version of this item item in the list and to refresh the list he needs to relaunch the app.
Yes, it's working with EventBus.
But as you can see here in the class there is no place for unregistering it from listening for UpdateItemEvent. Since there are no destructors in java(I don't believe that garbage collector should do this for me) I should handle this. Moreover the class registeres as listener in constructor (it happens several times, that's why you see this ugly if statement(if (!EventBus.getDefault().isRegistered(this))) You may ask me why not getting this adapter through Activity (there is the only one in the app) I tried building a chain AddDialogFragment -> WDActivity -> PlaceholderFragment -> ItemsAdapter
//AddDialogFragment
Context activity = getActivity();
if (activity instanceof WDActivity)
((WDActivity) activity).updateListItemFragment();
//WDActivity --beginTransaction().replace does not work here
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wd);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
...
public void updateListItemFragment() {
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.Fragment currentFragment = fragmentManager.findFragmentById(R.id.container);
if (currentFragment instanceof PlaceholderFragment && currentFragment != null) {
fragmentManager.beginTransaction().remove(currentFragment).commit();
fragmentManager.beginTransaction().add(R.id.container, currentFragment).commit();
((PlaceholderFragment)currentFragment).fillList();
}
//PlaceholderFragment
public class PlaceholderFragment extends Fragment {
private static final String LOG_TAG = "Logs";
private static final String ARG_SECTION_NUMBER = "section_number";
private ListView listViewItem;
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) {
if(getArguments().getInt(ARG_SECTION_NUMBER)==1)
return onCreateViewInputChart(inflater, container, savedInstanceState);
if(getArguments().getInt(ARG_SECTION_NUMBER)==2)
return onCreateViewManual(inflater, container, savedInstanceState);
return onCreateViewInputData(inflater, container, savedInstanceState);
}
private View onCreateViewManual(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_howto, container, false);
return rootView;
}
private View onCreateViewInputData(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_list_data, container, false);
findViewsByIdListItem(rootView);
fillList();
return rootView;
}
private View onCreateViewInputChart(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_chart, container, false);
return rootView;
}
//listViewItems
private void findViewsByIdListItem(View v) {
listViewItem = (ListView) v.findViewById(R.id.listViewItems);
}
public void fillList(){
Context activity = getActivity();
DatabaseManipulation dm = new DatabaseManipulation(activity);
ArrayList<DialogDataModel> aldm = dm.getItemsList();
dm.destroy();
ItemsAdapter innerAdapter = new ItemsAdapter(aldm, activity);
listViewItem.setAdapter(innerAdapter);
( (BaseAdapter) listViewItem.getAdapter() ).notifyDataSetChanged();
}
#Override
public void onAttach(Context activity) {
super.onAttach(activity);
}
#Override
public void onDetach(){
super.onDetach();
}
}
//SectionsPagerAdapter - just for your information
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
return PlaceholderFragment.newInstance(position);
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Enter your data";
case 1:
return "Chart";
case 2:
return "How to use it";
}
return null;
}
}
//ItemsAdapter is placed higher
This did not work. Finally I found out that the bottleneck is in linking PlaceholderFragment and ListAdapter: listViewItem is null everywhere except onCreateViewInputData. I could not figure out why. Google didn't give me the answer and I took it as a magic. Btw due to this feature I cannot use PlaceholderFragment's onAttach and onDetach for saying ItemsAdapter to register/unregister for receiving the event. This:
#Override
public void onAttach(Context activity) {
super.onAttach(activity);
( (ItemsAdapter) listViewItem.getAdapter() ).registerEventBus();
}
doesn't work for the same reason listViewItem is null. Maybe there is some way to manage with this more accurately?
Finally I cope with this: the bottleneck is in linking PlaceholderFragment and ListAdapter: listViewItem is null everywhere except onCreateViewInputData . Below is rewised SectionsPagerAdapter:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
Context activity;
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public SectionsPagerAdapter(FragmentManager fm, Context activity) {
super(fm);
this.activity = activity;
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
return PlaceholderFragment.newInstance(position);
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return activity.getString(R.string.chart);
case 1:
return activity.getString(R.string.weight_diary);
case 2:
return activity.getString(R.string.how_to);
}
return null;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
//maybe use adapater.getRegisteredFragment(viewPager.getCurrentItem());
}
}
and here is my call to the widget in the one of 3 fragments:
public void updateListItemFragment() {
android.support.v4.app.Fragment inputData = mSectionsPagerAdapter.getRegisteredFragment(1);
ListView lv = ((PlaceholderFragment)inputData).listViewItem;
//for test purposes I refill listview with no items - here you need to hand filled BaseAdapter instance: CustomAdapter innerAdapter = new CustomAdapter(ArrayList<yourDataModel>, getContext());
lv.setAdapter(null);
}
And as you've may already wondered there is no need for event bus anymore. Btw if the fragment is not crated yet you need to check it: details are here. Thanks to CommonsWare for quik reply and advice.

View Pager Android

I'm trying to implement a View Pager from : http://developer.android.com/training/animation/screen-slide.html
But I seem to have a problem when it comes to creating the page number. When debugging the downloaded zip from the previous mentioned website, first method called is create(int pageNumber) and afterwards onCreate() where you're getting the page number. In my case, it's the other way around, therefore I get a null pointer exception.
Here is my current implementation of the View Pager:
public class SingleCheckInDisplay extends android.support.v4.app.Fragment {
private Checkin data;
private FragmentManager fragmentManager;
private List<CheckinUser> enlooped;
private TextView checkInLocation;
private TextView checkInDescription;
private TextView checkInTime;
private Button cancelBtn;
private ImageButton singleCheckInEnloopBtn;
private ImageButton singleCheckInCancelBtn;
private HorizontalListView enloopedFriends;
public static final String ARG_PAGE = "page";
private int mPageNumber;
public static SingleCheckInDisplay create(int pageNumber) {
SingleCheckInDisplay fragment = new SingleCheckInDisplay();
Bundle args = new Bundle();
args.putInt(ARG_PAGE, pageNumber);
fragment.setArguments(args);
return fragment;
}
public SingleCheckInDisplay(Checkin data) {
this.data = data;
}
public SingleCheckInDisplay() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageNumber = 2;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_single_check_in_display, container, false);
enlooped = data.getCheckinUsers();
fragmentManager = getActivity().getSupportFragmentManager();
ImageView main_pic = (ImageView) v.findViewById(R.id.main_pic);
checkInLocation = (TextView) v.findViewById(R.id.single_check_in_location);
checkInDescription = (TextView) v.findViewById(R.id.single_check_in_desc);
checkInTime = (TextView) v.findViewById(R.id.single_check_in_time_text);
checkInTime.setText(data.getCheckinDate().toString());
enloopedFriends = (HorizontalListView) v.findViewById(R.id.sinlge_check_in_enlooped_list);
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.sm_profile)
.showImageForEmptyUri(R.drawable.sm_profile)
.showImageOnFail(R.drawable.sm_profile)
.cacheOnDisk(true)
.cacheInMemory(true)
.imageScaleType(ImageScaleType.EXACTLY)
.considerExifParams(true)
.displayer(new SimpleBitmapDisplayer())
.build();
ImageLoader.getInstance().displayImage(data.getImages(), main_pic, options);
checkInDescription.setText(data.getDescription());
checkInLocation.setText(data.getPlaceAddressAndName());
checkInLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Set a bundle with place ID, the rest will be obtained by calling Graph API
Bundle args = new Bundle();
args.putString("placeID", data.getPlaceId());
SingleCheckInPlace scp = new SingleCheckInPlace();
scp.setArguments(args);
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.beginTransaction().replace(R.id.container, scp).addToBackStack(null).commit();
}
});
SingleCheckInAdapter adapter = new SingleCheckInAdapter(getActivity(), enlooped);
enloopedFriends.setAdapter(adapter);
cancelBtn = (Button) v.findViewById(R.id.single_ck_display_cancel_button);
cancelBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MapsFilterFragment firstFragment = new MapsFilterFragment();
fragmentManager.beginTransaction().add(R.id.container, firstFragment).commit();
}
});
singleCheckInEnloopBtn = (ImageButton) v.findViewById(R.id.single_check_in_enloop_btn);
singleCheckInEnloopBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "Enlooped !", Toast.LENGTH_SHORT).show();
fragmentManager.popBackStack();
}
});
singleCheckInCancelBtn = (ImageButton) v.findViewById(R.id.single_check_in_no_btn);
singleCheckInCancelBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "Maybe next time", Toast.LENGTH_SHORT).show();
goBack();
}
});
return v;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onDetach() {
super.onDetach();
}
private void goBack() {
fragmentManager.popBackStack();
}
public int getPageNumber() {
return mPageNumber;
}
}
And here is the miplementation of the Pager itself:
public class ScreenSlideFragment extends android.support.v4.app.Fragment {
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
private static final int NUM_PAGES = 11;
public ScreenSlideFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_screen_slide, container, false);
mPager = (ViewPager) view.findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager());
mPager.setAdapter(mPagerAdapter);
return view;
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(android.support.v4.app.FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
return SingleCheckInDisplay.create(position);
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
}
DO like this
ViewPager mviewPager=(ViewPage)findViewById(R.id.urcontainer);
mviewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void OnPageSelected(int position) {
int page_number=position; //this will give u the current page number
}
});
`

Categories

Resources