updating custom view from database in viewpager when the fragment becomes visible - java

I have a couple of fragments in the viewpager, I set some values in the first fragment I have to update the very next fragment with the values from the first one, so I store the values created in the first fragment in the database and I'm trying to update the next view with the values from database, I'm using Room for database, right now what I'm trying to follow an approach described in this answer How to determine when fragment becomes visible in viewpager and what I'm doing is I'm creating a new thread to access the database and update the global variable bodyScore from the database. here is some code
public class MindFragment extends Fragment implements FragmentLifecycle {
SeekBar mindSeekBar;
private View rootView;
ViewPager viewPager;
private int seekBarProgress;
private Date date = new Date();
private static final String TAG = MindFragment.class.getSimpleName();
private LifeWheelView lview;
private volatile int bodyScore;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.activity_fill, container, false);
viewPager = getActivity().findViewById(R.id.viewpager);
lview = rootView.findViewById(R.id.lifeWheelView);
lview.setMind(bodyScore, 0);
}
#Override
public void onResumeFragment() {
Log.i(TAG, "onResumeFragment()");
Thread thread = new Thread(new Runnable() {
ScoreDao mScoreDao;
CategoryDao mCategoryDao;
#Override
public void run() {
LifewheelRoomDatabase db = LifewheelRoomDatabase.getDatabase(getContext());
mScoreDao = db.scoreDao();
mCategoryDao = db.categoryDao();
CategoryName categoryName = mCategoryDao.getCategoryByName("Body");
Integer category_id = categoryName.getId();
int bodyScoreExceptionFlag = 0;
while ( bodyScoreExceptionFlag == 0 ) {
try {
Score st = mScoreDao.getScoreByCategory(HelperMethods.getStartOfDay(), HelperMethods.getEndOfDay(), category_id);
if( st == null) {
bodyScore = 0;
}
else {
bodyScore = st.score;
}
bodyScoreExceptionFlag++;
} catch (NullPointerException e) {
continue;
}
}
}
});
thread.start();
lview.setMind(bodyScore, 0);
}
}
On the line lview.setMind(bodyScore,0); I'm getting a NullPointerException.
So my question is:
if the Fragment has been created before it's been viewed lview variable should be initialized. and when it becomes visible why when I'm trying to call a method on it why am I getting this exception.
How should the things like this be handled when updating the view ( not list or recycler view ) from the database in the view pager where the subsequent views are updated with the input from the last view.

If you have not done so yet, please look at sharing data between fragment using the view model.
Google has provided a simple way of Inter-Fragment Communication using Shared ViewModel.
The ViewModel and LiveData are components that came out of Google IO '17 but they became really mature and the standard as of Google IO '18, the architecture components are a lot more mature now.
It is a simple way to get an app up and running with minimal code.
Here is a github example of how to do exactly that. While there is a bug in that code, it should provide a good starting point.

Related

How to show 'NEW' tag after updating category recyclerView

How can I show NEW tag after updating category from database. Like this image
Only after if my category get Updated and show for 24 hrs.
This is my Adapter of Categories
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.viewHolder> {
ArrayList<RecipeModels> list;
Context context;
public RecyclerAdapter(ArrayList<RecipeModels> list, Context context) {
this.list = list;
this.context = context;
}
#NonNull
#Override
public viewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recycler_view_set,parent,false);
return new viewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull viewHolder holder, int position) {
RecipeModels models = list.get(position);
holder.imageView.setImageResource(models.getPic());
holder.textView.setText(models.getText());
holder.itemView.setOnClickListener(view -> {
// It is sending data to category activity.
//Intent intent = new Intent(context, CategoryActivity.class);
//intent.putExtra("title",fruits.get(position).getTitle());
//intent.putExtra("name", fruits.get(position).getName());
//context.startActivity(intent);
});
}
#Override
public int getItemCount() {
return list.size();
}
public static class viewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
TextView textView;
public viewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imageView);
textView = itemView.findViewById(R.id.textView);
}
}
}
I don't have any idea to do this. Any Idea or code to implement this? I can add more code if you want, but please help to solve this issue!
simply query your data layer for lastUpdated <= now() - 24hrs window. All the responses from DB would be new elements only.
If you want distinction b/w new and old data within 1 result set, you can use if-else in the query to set a boolean flag isNew. basically, something like
select D.id, (IF D.lastUpdated >= now() - 24hrs THEN 1 ELSE 0) AS isNew from table D;
where
LastUpdated is a column on table D of type timestamp.
And is filled by application while writing the data to DB.
This should better to offload on DB, rather than App, since DB can use indexes to do this filter rather quick.
The above answer assumes there is a DB associated with app
If that's not the case, you can't do this labelling since you app does not have any state to compute the diff with. All vectors are filled only when app starts
You can use DiffUtils in your adapter to get the Changed/Updated data.Based on that, you can set the visibility of "New" tag from your card.
class​ ​CategoriesAdapter​(): BaseAdapter<Category>(
diffCallback = ​object​ : ​DiffUtil​.​ItemCallback​<​Category​>()
{
override​ fun areItemsTheSame(oldItem: ​Category​, newItem: ​Category​): ​Boolean​ {
TODO​("​Not​ yet implemented")
   }
override​ fun areContentsTheSame(oldItem: ​Category​, newItem: ​Category​): ​Boolean​ {
         ​TODO​("​Not​ yet implemented")     }
}) { }
This is how your Base Adapter's declaration will look like:
abstract​ ​class​ ​BaseAdapter​<​T​>(
diffCallback​:​ ​DiffUtil​.​ItemCallback​<​T​>)
:​ ​ListAdapter​<​T​, ​BaseViewHolder​>(
AsyncDifferConfig​.​Builder​<​T​>(diffCallback)
.setBackgroundThreadExecutor(​Executors​.newSingleThreadExecutor())
.build()
) { }
If possible, try and get a timestamp for each image from the server.
Then, compare it to the android system's current time.
Using an if else statement, if the time gap is within the 24 hour range, display the 'new' label. or else, set it to View.GONE.
Now, If that's not possible, You would have to create a database within the app itself which also creates its own time stamp of the images.
Then compare for each image and display label when necessary.

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

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.

Custom adapter's asynchronous behaviour

I have created my own custom adapter class in my android app and I am calling it from one of my activity. I am adding some elements to the view from the adapter class and I need to access those variables from my activity class.
Now, ideally I would expect it to fill the view and then execute the further code in my activity class, but adapter class is taking some time to populate the view and in the meanwhile further code in my activity class is getting executed where no such elements have been added yet.
How do I handle this situation? I come from a js background. Do we have something like promises in java?
According to the answers I have my changed my code to this:
public class HomeActivity extends Activity {
GridView grid;
String text[] = {"Calendar","Uber","Weather","News","Youtube","Clock","Email","Maps","Twitter","Facebook"};
String list_app_name[] = {"calendar","uber","weather","news","youtube","clock","email","maps","twitter","facebook"};
String id_button[] = {"button_calendar","button_uber","button_weather","button_news","button_youtube","button_clock","button_email","button_maps","button_twitter","button_facebook"};
int image[] = {R.drawable.social_icons1,R.drawable.social_icons2,R.drawable.social_icons3,R.drawable.social_icons4,
R.drawable.social_icons5,R.drawable.social_icons6, R.drawable.social_icons7,R.drawable.social_icons8,
R.drawable.social_icons9,R.drawable.social_icons10};
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_home);
//setting up the adapter for gridView
grid = (GridView)findViewById(R.id.simpleGrid);
ImageAdapter ia = new ImageAdapter(this,image,text,id_button);
grid.setAdapter(ia);
ia.notifyDataSetChanged();
try {
initStateOfApps();
} catch (JSONException e) {
e.printStackTrace();
}
}
public void initStateOfApps() throws JSONException {
Log.d("here","here");
ArrayList<String> list = getEnabledApps();
Log.d("apps",list.toString());
for(int i=0;i<list.size();i++) {
String app_name = list.get(i);
ToggleButton button=null;
if(app_name.equals("calendar")) {
button = (ToggleButton)findViewById(R.id.button_calendar);
button.setChecked(true);
}
}
}
}
So what is happening is that I am creating some toggle buttons that are getting populated in the ImageAdapter class that I wrote.
Once the ImageAdapter is called, I call the notifydatasetchanged() on the adapter in order to update the view.
What I am doing inside the adapter is giving each of the toggle buttons some custom ID I wrote in res/values/ids.xml.
After using setId on each of the toggle buttons, I try using that ID in my activity class but it gives me nullPointerException in the initStateOfApps() where I am trying to change the state of button.
So even after using the notifyDataSetChanged it is still behaving the same.
ImageAdapter.java
public class ImageAdapter extends BaseAdapter {
private Context context;
private final int item_image[];
private final String item_text[];
private final String button_id[];
public ImageAdapter(Context context, int item_image[], String[] item_text,String[] button) {
this.context = context;
this.item_image = item_image;
this.item_text = item_text;
this.button_id = button;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(context);
// get layout from custom_gridview.xml
gridView = inflater.inflate(R.layout.item, null);
// set value into imageview
final ImageView image = (ImageView) gridView.findViewById(R.id.item_image);
image.setImageResource(item_image[position]);
// set value into textview
TextView text = (TextView) gridView.findViewById(R.id.item_text);
text.setText(item_text[position]);
final ToggleButton button_ = (ToggleButton) gridView.findViewById(R.id.item_button);
if(position==0) {
button_.setId(R.id.button_calendar);
image.setId(R.id.image_calendar);
}
button_.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener()
{
#Override
public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked)
{
if(context.getResources().getResourceEntryName(toggleButton.getId()).equals("button_calendar")) {
if(isChecked) {
try {
setStateOfApp("calendar","true");
} catch (JSONException e) {
e.printStackTrace();
}
Intent intent = new Intent(context, GoogleApp.class);
((Activity) context).startActivityForResult(intent,10);
} else {
try {
setStateOfApp("calendar","false");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}
} else {
gridView = (View) convertView;
}
return gridView;
}
}
You are trying to access View which is not a part of Activity's content view. So you can't access that view directly.
button = (ToggleButton)findViewById(R.id.button_calendar); // will return null
This ToggleButton will be null because findViewById will fail to find out ToggleButton in current content view because that view is present in your Adapter not in content view.
And you are getting nullpointerException because you are trying to access property on null view.
button.setChecked(true); // This button is null
In java we have <Future>, but I don't think it's what you're looking for.
The adapter (extending BaseAdaper) behaviour lets you create the adapter and, even in a second moment, change underlying data via getAdapter().setData() or whatever method you choose to add.
From this perspective, the adapter is a "stupid" component acting as A View containers, you should retrieve data elsewhere (CursorAdapter is different).
So, in your Activity, fill the adapter with needed data and, when finished, call adapter.notifyDatasetChanged(). This will inform the adapter that its own data has changed and it must refresh views
Yes, ideally, the population of the adapter should be coming from the outside. The adapter should really just take in a list of data and map that data to the views. For example, some method or task in the Activity could produce a list of data (probably asynchronously...since you mentioned it) that you then pass into the adapter and then you can notifyDataSetChanged() if you need to.
I can't see your code, but if for some reason the data is truly required to be populated from inside the adapter, you could use an event bus and subscribe to it in the Activity. I would recommend going with the first option, but here are some links if you choose to use an event bus:
https://github.com/greenrobot/EventBus
http://square.github.io/otto/
As per my understanding with your question
You are not properly managed the adapter data in your activity.
If any of the data or code interlinked with your adapter data or values
Then you can start those code after you retrieve the values or data and update the view in your activity.
Please note that use Viewholders in adapter to avoid slow populating and scrolling in listviews.
Viewholders will smooth your process.
I personally suggest you that
Please go with Recyclerview and RecyclerViewAdapter.
So many Android developers are using it.
If you have background tasks in adapter you can prefer to use RX Java or EventBus
If you provide the code
It's better for us to suggest exact solution

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