Android ViewPager: Destroy Fragment on Slide? - java

I am basically playing an animation on each fragment of the view pager. The animation plays when the user slides to the specific fragment. However, certain fragments don't play the animation the second time I visit them. That's because the view pager keeps them in memory.
I need to destroy each fragment after the user slides to another fragment. This way, the animations play every time I revisit those fragments.
Main View:
pager = (ViewPager) findViewById(R.id.guidepager);
mAdapter = new NewUserGuideAdapter(getSupportFragmentManager());
pager.setAdapter(mAdapter);
pager.setOffscreenPageLimit(0); //Tried this too. Didnt work
Fragment:
public class NewUserPage_Two extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_new_user_page__two, container, false);
//Play animation, etc
Animation animation_1 = AnimationUtils.loadAnimation(NewUserPage_Two.this.getActivity(), R.anim.abc_slide_in_bottom);
person1.setAnimation(animation_1);
return rootView;
}
Adapter:
public class NewUserGuideAdapter extends FragmentPagerAdapter {
public NewUserGuideAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new NewUserPage_One();
case 1:
return new NewUserPage_Two();
case 2:
return new NewUserPage_Three();
case 3:
return new NewUserPage_One();
case 4:
return new NewUserPage_One();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 5;
}
}
How can I amend my code guys?

ViewPager provide a method mViewPager.setOffscreenPageLimit(0);
Set the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state. Pages beyond this limit will be recreated from the adapter when needed.

Try this inside the fragment:
((BaseAdapter) *YourContainer*.getAdapter()).notifyDataSetChanged();
You can refer to: Refresh Current Fragment (ListView Data) remaining in the same activity

public void setOffscreenPageLimit(int limit) {
if (limit < DEFAULT_OFFSCREEN_PAGES) {
Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " +
DEFAULT_OFFSCREEN_PAGES);
limit = DEFAULT_OFFSCREEN_PAGES;
}
if (limit != mOffscreenPageLimit) {
mOffscreenPageLimit = limit;
populate();
}
}
That's the method body,DEFAULT_OFFSCREEN_PAGES=1by the way.I think google add this limits cause you need at least the 2 views between current item while you are sliding.
You can try using addOnPageChangeListener() and start your animation on onPageSelected.

Related

Past value from child fragment -> mainactivity cannot cast fragment_fr_event_Birthday to fragment_fr_event_wedding android studio

I have a Fragment inside the mainActivity, the fragment contains fragmentcontainerView which can be replaced by multiple child fragments with spinner onselectedListener. I want to able to pass those values from the child fragment via eg: Do something with: fragmentevent.TogetFName(); with a button in Mainactivity. In the parent fragment , I get the value from the child fragment(fragment_Birthday) with fragment_fr_event_birthday = (fragment_fr_event_Birthday) getChildFragmentManager().findFragmentById(R.id.fragment_event_child_fragment); and other value from other childfragment with frag_fr_event_wed = (fragment_fr_event_wedding) getChildFragmentManager().findFragmentById(R.id.fragment_event_child_fragment);, I know that they cannot be assigned with the different fragment class at once, but is there a clever way to do this or is there any other way I can pass value from child -> parent fragment->mainActivity
MainActivity:
public void onClick(View view){
case "Event":
Fragment_fr_Event fragment_fr_event = (Fragment_fr_Event) getSupportFragmentManager().findFragmentById(R.id.fragment_generated_mainView);
if(fragment_fr_event.TogetWedChildFcoupleName() !=null && fragment_fr_event.TogetEventType().equals("Wedding")){
testThis.setText(fragment_fr_event.TogetWedChildFcoupleName());
}if( fragment_fr_event.TogetEventType().equals("Birthday") && fragment_fr_event.TogetBirthdayFName() !=null){
testTat.setText(fragment_fr_event.TogetBirthdayFName());
}
}
ChildFragment(BirthdayFragment):
public String TogetEventBirthdayFName (){
EditText FBirthdayName = rootView.findViewById(R.id.Edittext_birthDay_FirstName);
return FBirthdayName.getText().toString();
}
ChildFragment(Wedding fragment):
public String toGetFcoupleName(){
EditText FCoupleName = rootView.findViewById(R.id.textView_wedding_Name);
return FCoupleName.getText().toString();
}
ParentFragment(EventFragment):
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Spinner TypeEventSpinner = rootview.findViewById(R.id.type_event);
TypeEventSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String tag_items = parent.getItemAtPosition(position).toString();
switch (tag_items){
case "Wedding":
frag_fr_event_wed = new fragment_fr_event_wedding();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_event_child_fragment, frag_fr_event_wed).disallowAddToBackStack().commit();
break;
case "Birthday":
fragment_fr_event_birthday = new fragment_fr_event_Birthday();
transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_event_child_fragment , fragment_fr_event_birthday).disallowAddToBackStack().commit();
break;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
public String TogetWedChildFcoupleName(){
if(frag_fr_event_wed !=null){
frag_fr_event_wed = (fragment_fr_event_wedding) getChildFragmentManager().findFragmentById(R.id.fragment_event_child_fragment);
return frag_fr_event_wed.toGetFcoupleName();
}return "Empty";
}
public String TogetBirthdayFName(){
if(fragment_fr_event_birthday != null){
fragment_fr_event_birthday = (fragment_fr_event_Birthday) getChildFragmentManager().findFragmentById(R.id.fragment_event_child_fragment);
return fragment_fr_event_birthday.TogetEventBirthdayFName();
}
return "Empty";
}
To be honest , I couldn't understand what you did there , but i got what you want , you want to communicate with parent's parent class , the way you are doing it made it so complicated even it's not readable , BUT of course there are always a good way to do something , in your case there are Android Navigation Component , which give you the simplicity and power to do make it much more easy to handle , You can put all your fragment in one graph and from within the destinations "fragment are called destinations here" you can communicate with other fragment and the parent using actions and global actions "going from one fragment to another is called action here" parameters, but there are no need to a parent's parent here , all destinations and its parent can share one ViewModel which will allow you to share data all around your app .
You can read more if it sound good to you here

Android ListView Adaptor changing colour when you scroll past the item

Okay so we have some realm results returning a set of stock orders that we have made. Depending on if the stock order is fully checked in we are showing the background colour of the row item as green or blue using an if statement in the adaptor.
The issue is that on load the orders display as green/blue correctly. But when you scroll down the blue ones are changing to green. (See Images). We think it may be that the data is getting changed somewhere but not sure why this would be happening as we are just scrolling on the page.
Code that creates this:
StockOrdersFragment.java
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
myView = inflater.inflate(R.layout.stock_orders_layout, container, false);
listView = myView.findViewById(R.id.listView);
stockOrdersService = new StockOrdersService(this);
stockOrdersService.fetchFromServer(getActivity());
fetchStockOrders();
return myView;
}
public void fetchStockOrders()
{
stockOrders.clear();
RealmResults<StockOrder> savedStockOrders = stockOrdersService.all();
stockOrders.addAll(savedStockOrders);
StockOrdersAdaptor adaptor = new StockOrdersAdaptor(stockOrders, getActivity());
listView.setAdapter(adaptor);
}
#Override
public void ordersReceived() {
fetchStockOrders();
}
StockOrdersAdaptor.java (The bit that does the colour )
lastPosition = position;
if(stockOrder != null){
viewHolder.stockOrderId.setText(String.valueOf(stockOrder.id));
viewHolder.supplierName.setText(stockOrder.supplier.name);
if (stockOrder.allItemsHaveBeenReceived()) {
convertView.setBackgroundResource(R.color.colorGreen);
}
}
// Return the completed view to render on screen
return convertView;
The allItemsHaveBeenRecieved()
public Boolean allItemsHaveBeenReceived()
{
for (StockOrderDetails detail: details) {
if (detail.quantity != detail.quantityReceived) {
return false;
}
}
return true;
}
Add else statement here:
if (stockOrder.allItemsHaveBeenReceived()) {
convertView.setBackgroundResource(R.color.colorGreen);
} else {
convertView.setBackgroundResource(R.color.colorBlue);
}
Problem is when your item gets recycled it remains dirty. Make sure you are populating all UI items from your list item layout every time adapter binds to it.

Shared Element Transition is not exiting properly

I have fragment from which I'm launching activity with shared element transition that has viewpager in it, the enter transition works fine but when i scroll in view pager and finish transition the shared image comes from left side which is not desired it should reposition itself to where it was launched, here is my code:
Intent myIntent = new Intent(getActivity(), EnlargeActivity.class);
ActivityOptionsCompat options = ActivityOptionsCompat.
makeSceneTransitionAnimation(getActivity(),
imageView,
ViewCompat.getTransitionName(imageView));
startActivity(myIntent, options.toBundle());
I'm updating view and its name in activity that contains viewpager when finishing activity, but its going with blink:
public void finishAfterTransition() {
setEnterSharedElementCallback(new SharedElementCallback() {
#Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
// Clear all current shared views and names
names.clear();
sharedElements.clear();
ViewGroup viewGroup = (ViewGroup) viewPagerDetail.getAdapter()
.instantiateItem(viewPagerDetail, viewPagerDetail.getCurrentItem());
if (viewGroup == null) {
return;
}
// Map the first shared element name to the child ImageView.
sharedElements.put(viewGroup.findViewById(R.id.img).getTransitionName(), viewGroup.findViewById(R.id.img));
// setExitSharedElementCallback((SharedElementCallback) this);
}
});
super.finishAfterTransition();
Basically, Android start the transition with your pre-defined View and transitionName and automatically use the same properties for the return transition. When you change your focused View in ViewPager, Android doesn't know about that and keep the transition on the previous one on its way back. So you need to inform Android about the changes:
Remap the transition properties: Use setEnterSharedElementCallback to change the transitionName and View to the new one before returning from Activity2.
Wait for the Activity1 to finish rendering addOnPreDrawListener.
It's a bit complex in the final implementation. But you can look at my sample code https://github.com/tamhuynhit/PhotoGallery. I try to implement the shared-element-transition from many simple to complex sections.
Your problem appeared from Level 3 and solved in Level 4.
I am writing a tutorial about this but it's not in English so hope the code can help
UPDATE 1: Work flow
Here is how I implement it in my code:
Override finishAfterTransition in Activity2 and call setEnterSharedElementCallback method to re-map the current selected item in ViewPager. Also, call setResult to pass the new selected index back to previous activity here.
#Override
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void finishAfterTransition() {
setEnterSharedElementCallback(new SharedElementCallback() {
#Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
View selectedView = getSelectedView();
if (selectedView == null)
return;
// Clear all current shared views and names
names.clear();
sharedElements.clear();
// Store new selected view and name
String transitionName = ViewCompat.getTransitionName(selectedView);
names.add(transitionName);
sharedElements.put(transitionName, selectedView);
setExitSharedElementCallback((SharedElementCallback) null);
}
});
Intent intent = new Intent();
intent.putExtra(PHOTO_FOCUSED_INDEX, mCurrentIndex);
setResult(RESULT_PHOTO_CLOSED, intent);
super.finishAfterTransition();
}
Write a custom ShareElementCallback so I can set the callback before knowing which View is going to be used.
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static class CustomSharedElementCallback extends SharedElementCallback {
private View mView;
/**
* Set the transtion View to the callback, this should be called before starting the transition so the View is not null
*/
public void setView(View view) {
mView = view;
}
#Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
// Clear all current shared views and names
names.clear();
sharedElements.clear();
// Store new selected view and name
String transitionName = ViewCompat.getTransitionName(mView);
names.add(transitionName);
sharedElements.put(transitionName, mView);
}
}
Override onActivityReenter in Activity1, get the selected index from the result Intent. Set setExitSharedElementCallback to re-map new selected View when the transition begins.Call supportPostponeEnterTransition to delay a bit because your new View may not be rendered at this point. Use getViewTreeObserver().addOnPreDrawListener to listen for the layout changes, find the right View by the selected index and continue the transition supportStartPostponedEnterTransition.
#Override
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void onActivityReenter(int resultCode, Intent data) {
if (resultCode != LevelFourFullPhotoActivity.RESULT_PHOTO_CLOSED || data == null)
return;
final int selectedIndex = data.getIntExtra(LevelFourFullPhotoActivity.PHOTO_FOCUSED_INDEX, -1);
if (selectedIndex == -1)
return;
// Scroll to the new selected view in case it's not currently visible on the screen
mPhotoList.scrollToPosition(selectedIndex);
final CustomSharedElementCallback callback = new CustomSharedElementCallback();
getActivity().setExitSharedElementCallback(callback);
// Listen for the transition end and clear all registered callback
getActivity().getWindow().getSharedElementExitTransition().addListener(new Transition.TransitionListener() {
#Override
public void onTransitionStart(Transition transition) {}
#Override
public void onTransitionPause(Transition transition) {}
#Override
public void onTransitionResume(Transition transition) {}
#Override
public void onTransitionEnd(Transition transition) {
removeCallback();
}
#Override
public void onTransitionCancel(Transition transition) {
removeCallback();
}
private void removeCallback() {
if (getActivity() != null) {
getActivity().getWindow().getSharedElementExitTransition().removeListener(this);
getActivity().setExitSharedElementCallback((SharedElementCallback) null);
}
}
});
// Pause transition until the selected view is fully drawn
getActivity().supportPostponeEnterTransition();
// Listen for the RecyclerView pre draw to make sure the selected view is visible,
// and findViewHolderForAdapterPosition will return a non null ViewHolder
mPhotoList.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
mPhotoList.getViewTreeObserver().removeOnPreDrawListener(this);
RecyclerView.ViewHolder holder = mPhotoList.findViewHolderForAdapterPosition(selectedIndex);
if (holder instanceof ViewHolder) {
callback.setView(((ViewHolder) holder).mPhotoImg);
}
// Continue the transition
getActivity().supportStartPostponedEnterTransition();
return true;
}
});
}
UPDATE 2: getSelectedItem
To get selected View from the ViewPager, don't use getChildAt or you get the wrong View, use findViewWithTag instead
In the PagerAdapter.instantiateItem, use position as tag for each View:
#Override
public View instantiateItem(ViewGroup container, int position) {
// Create the View
view.setTag(position)
// ...
}
Listen to onPageSelected event to get the selected index:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
mSelectedIndex = position;
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Call getSelectedView to get the current view by the selected index
private View getSelectedView() {
try {
return mPhotoViewPager.findViewWithTag(mSelectedIndex);
} catch (IndexOutOfBoundsException | NullPointerException ex) {
return null;
}
}
This is actually a default behavior, I was struggling SharedElementTransitions a lot, but I have nested fragments. I got my solution from an article (very recent article), it shows an implementation with a RecyclerView, which I assume you have. In short, the solution is to override onLayoutChange :
recyclerView.addOnLayoutChangeListener(
new OnLayoutChangeListener() {
#Override
public void onLayoutChange(View view,
int left,
int top,
int right,
int bottom,
int oldLeft,
int oldTop,
int oldRight,
int oldBottom) {
recyclerView.removeOnLayoutChangeListener(this);
final RecyclerView.LayoutManager layoutManager =
recyclerView.getLayoutManager();
View viewAtPosition =
layoutManager.findViewByPosition(MainActivity.currentPosition);
// Scroll to position if the view for the current position is null (not
// currently part of layout manager children), or it's not completely
// visible.
if (viewAtPosition == null
|| layoutManager.isViewPartiallyVisible(viewAtPosition, false, true)){
recyclerView.post(()
-> layoutManager.scrollToPosition(MainActivity.currentPosition));
}
}
});
Here is the article, and you will also find the project on GitHub.

Load more data when FragmentStatePagerAdapter reaches the end of items

Question from Noob android developer
Issue Defitition :
I'm trying to achieve endless scrolling implement functionality of loading more data via network request when the FragmentStatePagerAdapter reaches last item, currently i'm setting static number for getCount to 10//, what i'd like to do is trigger a network request as soon as it hits 7th item to get 10 more items and refresh the list, keeping the cycle going and potentially end up with more than 100 items hence why i'm using FragmentStatePagerAdapter, also store/cache the data so to support left to right & right to left swipe
Here's what i've tried so far
Read this article infinite viewpager however it only works for
limited set of fragments perhaps a static number, what i'm trying to
do is more dynamic as such I dont have a fixed getCount.
Read the article endless scrolling adapters, i'm not trying to use
recycler view as viewpager works just fine for what i'm trying to do
Few more pageradapter implementations
what i've learnt so far
need to override getcount to return the maximum possible value
public int getCount() {
#Override
return Integer.MAX_VALUE;
}
*I'm not sure if should also override getItemPosition or implement some kind on pageListener there are many examples available online using pagerAdapter/fragmentPageradapter i'm getting confused as to which ones are related to FragmentStatePagerAdapter and which ones are not
*
// My Framgent class
public class ScreenSlidePageFragment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.activity_screen_slide_page_fragment,container,false);
return rootView;
}
public static ScreenSlidePageFragment newInstance (String url){
ScreenSlidePageFragment newFragment = new ScreenSlidePageFragment();
Bundle args = new Bundle();
args.putString("imagePathUrl", url);
newFragment.setArguments(args);
return newFragment;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ImageView mImageView = (ImageView) getView().findViewById(R.id.imageView);
String imageUrl = getArguments().getString("imagePathUrl");
if (imageUrl==null){
Log.i("ScreenSlidePageFragment","no data passed");
}else {
Glide.with(this).load(imageUrl).into(mImageView);
}
}
}
// My adapter implementation
public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
List<Resource> mResources;
String url;
Context mContext;
private int NUM_PAGES = 5;
private int currentPosition = 0;
public ScreenSlidePagerAdapter(FragmentManager fm, List<Resource> res,
Context context) {
super(fm);
mResources = res;
mContext = context;
}
#Override
public Fragment getItem(int position) {
if (mResources != null & mResources.size() > 0){
url = mResources.get(position).getUrl();
Log.i("url",url);
return ScreenSlidePageFragment.newInstance(url);
}else {
Toast.makeText(mContext,"no results returned",Toast.LENGTH_LONG).show();
return null;
}
}
#Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
any help will be highly appreciated
Use FragmentStatePagerAdapter (support.v13) and implement getItemPosition like this:
public int getItemPosition(Object object) {
return POSITION_NONE;
}
https://hedgehogjim.wordpress.com/2013/10/03/android-updatable-swipe-navigation-with-fragmentstatepageradapter/
return POSITION_NONE "Causes adapter to reload all Fragments when notifyDataSetChanged is called"
Add a OnPageChangeListener to your ViewPager and load more data after comparing the given position value with your current data size
#Override
public void onPageSelected(int position) {
//Load previous data set if position == 0
//Load next data set if position == myAdapter.mResources.size() - 1
}
After the new data set has been loaded (and sorted), call myAdapter.notifyDataSetChanged() then calculate and set the new index to match the old offset so the user don't see any shift
myViewPager.setCurrentItem(myNewIndex, false)
Note: Sorting and new index calculation is only necessary when loading a previous data set.

Android Fragment issue

i'm new to Android, (not programming, or even Java) so bear with me.
I'm trying to get a handle on the use of fragments.
I've got a project that I've created using the default swipe/actionbar. I've extended this further to handle the settings i want.... however i don't quite understand what's going on/how to fix this.
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
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 a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
// Show 8 total pages.
return 8;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
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);
case 3:
return getString(R.string.title_section4).toUpperCase(l);
case 4:
return getString(R.string.title_section5).toUpperCase(l);
case 5:
return getString(R.string.title_section6).toUpperCase(l);
case 6:
return getString(R.string.title_section7).toUpperCase(l);
case 7:
return getString(R.string.title_section8).toUpperCase(l);
}
return null;
}
}
/**
* A dummy fragment representing a section of the app, but that simply
* displays dummy text.
*/
public class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public String ARG_SECTION_NUMBER = "section_number";
public DummySectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
int position;
position = getArguments().getInt(ARG_SECTION_NUMBER)-1;
View rootView;
TextView dummyTextView;
I don't really want anything static or final here, and I've got it mostly worked out but I don't understand the following line or how to fix it. I kinda get what it's doing.
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
The error is: cannot make a static reference to the non-static field DummySectionFragment.ARG_SECTION_NUMBER
There is probably a simple fix for this, i just am unfamiliar enough with Android and Java, as my current job i spend all my time in SQL Server.
-- EDITED ADDITIONS
i'm not opposed to anything static or final etc. the problem i'm not quite understanding is when i want to DO something in each of those fragments. I have a textview on each of those layouts and i want to be able to manipulate them say in a loop. I think i'm stuck in a circle and can't figure my way out... lol.
For example below the code I put above is
case 4:
rootView = inflater.inflate(R.layout.fragment_main_location,container, false);
dummyTextView= (TextView) rootView .findViewById(R.id.section_label);
// location
Button btnShowLocation = (Button) rootView.findViewById(R.id.btnShowLocation);
Button btnShowDBLocList = (Button) rootView.findViewById(R.id.btnShowDBLocList);
Button btnLocationsCount = (Button) rootView.findViewById(R.id.btnLocationsCount);
Button btnTruncateDBLocationsTable = (Button) rootView.findViewById(R.id.btnTruncateDBLocationsTable);
btnTruncateDBLocationsTable.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Activity activity = getActivity();
int intCount = 0;
/*if (activity != null) {
//dummyTextView.setText("");
try {
locationDatabaseHandler.truncateLocationTable();
intCount = locationDatabaseHandler.getLocationCount();
} catch (Exception e){
//dummyTextView.append(e.toString());
}
//dummyTextView.append("Count:" + intCount + "\n\n");
Toast.makeText(activity, "toast_you_just_clicked_a_fragment btnTruncateDBLocationsTable button", Toast.LENGTH_LONG).show();
}*/
}
});
dummyTextView = (TextView) rootView .findViewById(R.id.section_label);
dummyTextView.append("\nLocation Stuff\n");
break;
//dummyTextView.append("Count:" + intCount + "\n\n");
I run into a circle where if I dummyTextView try to use the dummmyText w/in the onClick event, it says that i need to make it static (quick fix) with a complaining error of : cannot refer to a non-final variable dummy7Text inside an indder class defined in a different method.
I've added a variables to handle this inside the onCreate that get filled for (LayoutInflater and Viewgroup, and then reference them w/in the onclick (not shown), but when i go in and instansiate ... nothing happens with the textviews...
There is something i'm not quite getting here, and once i get by that hurdle, i'll have this by the balls, and will be able to make it do what i want.
I don't really want anything static or final here
Why? They will not negatively impact performance, nor are they a sign of poor coding practices.
I don't understand the following line
Every Fragment can be created with a Bundle containing any number of key-value pairs. DummySectionFragment.ARG_SECTION_NUMBER is a the key (a String), and position + 1 is the value. Thus this code is telling the new DummySectionFragment which section of content the Fragment should show.
This method is preferable to putting these arguments in a constructor because your custom constructor for a Fragment isn't guaranteed to be called. There are many ways for Android to generate Fragments, so this lowers the possibility of problems such as NullPointerExceptions.
the error is: cannot make a static reference to the non-static field DummySectionFragment.ARG_SECTION_NUMBER
As you seem to know, DummySectionFragment.ARG_SECTION_NUMBER is referring to a static field within the DummySectionFragment class called ARG_SECTION_NUMBER. By making this field non-static, you can no longer reference this constant value without a DummySectionFragment instance.
Another option (if you really don't want a static field) would be to hardcode the String. Thus your code would be:
args.putInt("section_number", position + 1);
However, a public static field is a much better coding practice and will prevent silly mistakes with typos in your Strings.
I run into a cirle where if i dummyTextView try to use the dummmyText w/in the onClick event, it says that i need to make it static (quick fix) with a complaining error of : cannot refer to a non-final variable dummy7Text inside an indder class defined in a different method.
Instead of using an anonymous inner class, I would let your Fragment implement OnClickListener.
For example:
public class MyFragment extends Fragment implements OnClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// ...
Button btnTruncateDBLocationsTable = (Button) rootView.findViewById(R.id.btnTruncateDBLocationsTable);
btnTruncateDBLocationsTable.setOnClickListener(this);
// ...
}
#Override
public void onClick(View v) {
// You can reference dummyTextView here without any problems
}
}
that means that ARG_SECTION_NUMBER should be declared as public static. Better if it declared as public static final

Categories

Resources