I have a listener excerpt below which contains the variable degree.
public class CustomOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
//Define Components
public EditText text;
public Spinner spinner1;
//Define Variables
public String degree;
public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
//Set the selected item on spinner1 to the variable tempValue
String tempValue = spinner1.getSelectedItem().toString();
degree = "jobby";
}
I am trying to access that variable within my ViewPager adapter like so:
public class MyPagerAdapter extends FragmentPagerAdapter {
public CustomOnItemSelectedListener selectedListener;
[...]
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return resultFragment.newInstance(selectedListener.degree);
case 1: return resultFragment.newInstance("resultFragment, Instance 2");
default: return resultFragment.newInstance("resultFragment, Default");
}
}
[...]
}
And in my MainActivity
protected void onCreate(Bundle savedInstanceState) {
[...]
myPager = new MyPagerAdapter(getSupportFragmentManager());
selectedListener = new CustomOnItemSelectedListener();
addListenerOnSpinnerItemSelection();
myPager.selectedListener = selectedListener;
}
The issue I am having is that I am unable to access the variable of degree. If I set the value of the variable at the top of the listener class like so
public String degree = "jobby";
Then I can access the variable.
I am trying to write an if statement within the listener, and depending on which item of the spinner is selected, the variable changes.
How can I access the variable within the listener class?
I think it's because you need initialize the variable, try this:
public String degree = null;
And make sure when you use the variable it's with the correct value, to try avoid NullPointerExceptions.
In CustomOnItemSelectedListener#onItemSelected the fragment needs to be replaced using the Activity's FragmentManager.
Refer to the Fragment example code (scroll down to the showDetails() method). However, instead of FragmentManager#findFragmentById you should use FragmentManager#findFragmentByTag.
Perhaps something like this:
FragmentManager fragManager = getFragmentManager();
FragmentTransaction xact = fragManager.beginTransaction();
ResultFragment resultFragment = (ResultFragment)fragManager.findFragmentByTag(selectedListener.degree);
if(resultFragment == null) {
mList = resultFragment.newInstance(selectedListener.degree);
xact.add(R.id.view_container, resultFragment, selectedListener.degree);
}
xact.commit();
Be careful, though, if degree varies wildly then this would result in many Fragments contained in the FragmentManger. In this case you should remove the unused Fragments as needed.
Related
I occasionally get NullPointerException when entering fragment. It happens when the app was in the background for a long time and then I open it and swipe to this fragment.
public class SummaryFragment extends Fragment implements FragmentLifecycle {
private static final String TAG = "DTAG";
private DateFormat dateFormatName;
private Preference prefs;
private List<String> monthList;
private TextView totalTimeFullTv;
private TextView totalTimeNetTv;
private TextView averageTimeTv;
private TextView overUnderTv;
private TextView minTimeTv;
private TextView maxTimeTv;
private TextView vacationsTv;
private TextView sickTv;
private TextView headlineTv;
private TextView overUnderTvH;
private OnFragmentInteractionListener mListener;
public SummaryFragment() {
// Required empty public constructor
}
public static SummaryFragment newInstance(String param1, String param2) {
SummaryFragment fragment = new SummaryFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View RootView = inflater.inflate(R.layout.fragment_summary, container, false);
dateFormatName = new SimpleDateFormat(getResources().getString(R.string.month_text));
monthList = Arrays.asList(new DateFormatSymbols().getMonths());
prefs = new Preference(GeneralAdapter.getContext());
totalTimeFullTv = RootView.findViewById(R.id.textView_sum_ttf);
totalTimeNetTv = RootView.findViewById(R.id.textView_sum_ttn);
averageTimeTv = RootView.findViewById(R.id.textView_sum_av);
overUnderTv = RootView.findViewById(R.id.textView_sum_ou);
overUnderTvH = RootView.findViewById(R.id.textView_sum_ou_h);
minTimeTv = RootView.findViewById(R.id.textView_sum_min);
maxTimeTv = RootView.findViewById(R.id.textView_sum_max);
vacationsTv = RootView.findViewById(R.id.textView_sum_vac);
sickTv = RootView.findViewById(R.id.textView_sum_sick);
headlineTv= RootView.findViewById(R.id.textView_sum_headline);
return RootView;
}
private void refreshData() {
if (prefs == null)
{
prefs = new Preference(GeneralAdapter.getContext());
}
String month = prefs.getString(Preference.CURRENT_MONTH);
MonthData monthData = Calculators.CalculateLocalData(MainActivity.db.getAllDays(month));
totalTimeFullTv.setText(monthData.getTotalTimeFull()); //Crash here
totalTimeNetTv.setText(monthData.getTotalTimeNet());
averageTimeTv.setText(monthData.getAverageTime());
overUnderTv.setText(monthData.getOverUnder());
if (monthData.getOverUnderFloat()<0)
{
overUnderTvH.setText(R.string.sum_over_time_neg);
overUnderTv.setTextColor(ContextCompat.getColor(GeneralAdapter.getContext(),R.color.negative_color));
}
else
{
overUnderTvH.setText(R.string.sum_over_time_pos);
overUnderTv.setTextColor(ContextCompat.getColor(GeneralAdapter.getContext(),R.color.positive_color));
}
minTimeTv.setText(monthData.getMinTime());
maxTimeTv.setText(monthData.getMaxTime());
vacationsTv.setText(""+monthData.getVacations());
sickTv.setText(""+monthData.getSick());
headlineTv.setText(month);
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttachFragment(Fragment childFragment) {
super.onAttachFragment(childFragment);
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
#Override
public void onPauseFragment() {
}
#Override
public void onResumeFragment()
{
refreshData();
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
MainActivity viewPager:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
int currentPosition = 0;
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
FragmentLifecycle fragmentToHide = (FragmentLifecycle) adapter.getItem(currentPosition);
fragmentToHide.onPauseFragment();
FragmentLifecycle fragmentToShow = (FragmentLifecycle) adapter.getItem(position);
fragmentToShow.onResumeFragment(); //Crash start
currentPosition = position;
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Log:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: michlind.com.workcalendar, PID: 25038
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at michlind.com.workcalendar.mainfragments.SummaryFragment.refreshData(SummaryFragment.java:99)
at michlind.com.workcalendar.mainfragments.SummaryFragment.onResumeFragment(SummaryFragment.java:147)
at michlind.com.workcalendar.activities.MainActivity.onPageSelected(MainActivity.java:84)
at android.support.v4.view.ViewPager.dispatchOnPageSelected(ViewPager.java:1941)
at android.support.v4.view.ViewPager.scrollToItem(ViewPager.java:680)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:664)
at android.support.v4.view.ViewPager.onTouchEvent(ViewPager.java:2257)
at android.view.View.dispatchTouchEvent(View.java:11776)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2962)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2643)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:448)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1829)
at android.app.Activity.dispatchTouchEvent(Activity.java:3307)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:410)
at android.view.View.dispatchPointerEvent(View.java:12015)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4795)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4609)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4293)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4350)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6661)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6635)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6596)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6764)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:142)
at android.app.ActivityThread.main(ActivityThread.java:6494)
UPDATE:
I eventually used:
#Override
public void onPageSelected(int position) {
Fragment fragment = adapter.getFragment(position);
if (fragment != null) {
fragment.onResume();
}
}
At my MainActivity, and used onResume() at each fragment. And this solution for the adapter:
http://thedeveloperworldisyours.com/android/update-fragment-viewpager/
The problem is, that you are trying to access views too early: view hierarchy is not created at that point yet.
If you post an event, that would take place on the next frame, you are guaranteed, that view hierarchy would be already setup:
#Override
public void onResumeFragment() {
new Handler().post(new Runnable() {
#Override
public void run() {
refreshData();
}
});
}
I faced the same problem when I had implemented custom life cycles for ViewPager. I think you are using FragmentStatePagerAdapter to populate fragments with ViewPager. As we know FragmentStatePagerAdapter destroys all the fragments when they lose focus. We need to provide same object for every page using singleton pattern.
In your code, Fragment creation can be like below for singleton pattern.
private SummaryFragment mInstance;
private SummaryFragment() {
// Required empty public constructor
}
public static SummaryFragment newInstance(String param1, String param2) {
if(mInstance == null)
mInstance = new SummaryFragment();
return mInstance;
}
Doing this has solved my problem. If this does not work for you? Can you share your PagerAdapter class.
onResumeFragment() is getting invoked before the creation of all the views of this fragment.
Try recreating newInstance first and then invoke onResumeFragment of FragmentLifeCycle interface in your Activity.
ViewPager keeps several items on either side attached (i.e. fragments resumed), however FragmentPagerAdapter uses Fragment.setUserVisibleHint to indicate, which item is current. Leverage that instead.
Here's what to do to leverage user visible hint:
Remove the OnPageChangeListener.
Ditch the FragmentLifecycle interface.
Set your fragment like so:
(in Kotlin, but you'll get the gist)
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if (isVisibleToUser && isResumed) {
// Do stuff.
}
}
override fun onResume() {
super.onResume()
if (userVisibleHint) {
// Do the same stuff.
}
}
More info
FragmentPagerAdapter.getItem is a factory method. It's always supposed to return you a new instance of a fragment. If you tried to cache them, remove the cache (1) and don't use getItem yourself (2).
Code that sometimes crashes and sometimes doesn't is a b**** to debug. This can be caused by reusing fragments when you're not supposed to.
A new fragment instance is not attached, has no reason to create views and will be garbage collected once you leave onPageSelected.
You are using OnPageChangeListener incorrectly. This is not a safe way to control view lifecycle events. You need to use PagerAdapter in conjunction with ViewPager and override its instantiateItem / destroyItem callbacks.
See this example: http://android-er.blogspot.com/2014/04/example-of-viewpager-with-custom.html
PagerAdapter is to ViewPager what ListAdapter is to ListView, you need both to make your system work correctly.
Use onViewCreated() callback method of fragment to update your data that way you are sure that all your views are laid out perfectly.
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
refreshData();
}
Using Handler can still be risky as you can't be sure the view are inflated or not.
PROBLEM
The lifecycle of a Fragment is independent. You cannot be sure that when an onPageSelected() gets registered, that fragment has already been laid out. It's is an asynchronous event. So you cannot rely on this callback.
But on the other hand, you cannot also rely only on the onResume(), since in a ViewPager, the pages adjacent to the currently visible page are preloaded.
SOLUTION
Principally you will need to refreshData() when the fragment is visible to user and actively running. The definition of onResume() says the same:
Called when the fragment is visible to the user and actively running. (...)
So simply call refreshData() in the onResume() of your fragment, and don't worry if you notice this getting called while the ViewPager wasn't really showing this page.
Like most people said you need to make sure your fragment is active and visible to the user. i had a similar problem. I used onHiddenChanged to decided when to reload data.
#Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (!hidden) {
refreshData();
}
}
You should inflate your layout in onCreateView but shouldn't initialize other views using findViewById in onCreateView.
here is a code from the FragmentManager
// This calls onCreateView()
f.mView = f.performCreateView(f.getLayoutInflater(f.mSavedFragmentState), null, f.mSavedFragmentState);
// Null check avoids possible NPEs in onViewCreated
// It's also safe to call getView() during or after onViewCreated()
if (f.mView != null) {
f.mView.setSaveFromParentEnabled(false);
if (f.mHidden) f.mView.setVisibility(View.GONE);
f.onViewCreated(f.mView, f.mSavedFragmentState);
}
It's better to do any assignment of subviews to fields in onViewCreated. This is because the framework does an automatic null check for you to ensure that your Fragment's view hierarchy has been created and inflated (if using an XML layout file) properly.
once the view is created then initialize your views.
Add this check in refreshData() method:
if (isAdded() && getActivity() != null)
I get the next error: java.lang.IllegalStateException: Fragment already added.
This is a layout getting inflated each time I change tab, as seen in this photo:
![FirstTab]http://prntscr.com/h4e8pc
![SecondTab]http://prntscr.com/h4ebyn
So i get the idea of the problem, but I've tried many ways to fix it with no result. I've tried to use .replace instead of .add, that way it doesnt crash but the map is not loaded. And also tried to delete the fragment as soon as I switch to that tab but the result is similar to the .replace one.
case R.id.navigation_dashboard:
frame = (FrameLayout) findViewById(R.id.content);
frame.removeAllViewsInLayout();
LayoutInflater.from(getApplicationContext())
.inflate(R.layout.activity_prueba_dashboard, frame, true);
fragmentTransaction =
getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.content2, mMapFragment);
fragmentTransaction.commit();
mMapFragment.getMapAsync(my_maps_class);
I believe it's much cleaner to use viewpager in that situation. Check this code :
public class HomeViewPagerAdapter extends FragmentPagerAdapter {
public static final int FRAGMENT_A_INDEX = 0;
public static final int FRAGMENT_B_INDEX = 1;
public static final int FRAGMENT_C_INDEX = 2;
public static final int FRAGMENTS_COUNT = 3;
public HomeViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case FRAGMENT_A_INDEX:
return FragmentA.newInstance();
case FRAGMENT_B_INDEX:
return FragmentB.newInstance();
case FRAGMENT_C_INDEX:
return FragmentC.newInstance();
default:
return null;
}
}
#Override
public int getCount() {
return FRAGMENTS_COUNT;
}
}
and then link the adapter with the ViewPager in the hosting appcompat activity as here :
HomeViewPagerAdapter homeTabsAdapter = new HomeViewPagerAdapter(getSupportFragmentManager());
homeTabsViewPager.setAdapter(homeTabsAdapter);
and you can easily switch between fragments by calling :
homeTabsViewPager.setCurrentItem(HomeViewPagerAdapter.FRAGMENT_A_INDEX, false);
You seen to be trying replacing the content of the same Fragment, in this case you dont need the FragmentTransaction.
The solution is to create a second fragment on which you have the map, in this case the Transaction is needed.
I have an android fragment, that has a listview. for that listview I implemented an inner OnItemClickListener class.
When there's a click, I save the selection in a global variable called SelectedIndex.
If I click again on that list, I can see the previous selection correctly, So its saving the state on the global variable correctly.
The problem is when I try to access to that same global variable from another inner class, for example, one class used for listen to clicks on a button. Is always showing the value I used for initialize the varialbe (-1).
The code of the fragment:
/**
* A placeholder fragment containing the view for the recentCalls list
*/
public class RecentCallsFragment extends Fragment {
private Cursor cursorAllRows;
private RecentCallsTable rcTable;
private ListView list;
private RecentCallsAdapter adapter;
Button btnDelete, btnCreditRequest, btnCreditBlock, btnSendTo;
int selectedIndex; //this is the global variable that I am using.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rcTable = new RecentCallsTable(getActivity());
cursorAllRows = rcTable.getRecentCallsCursor();
adapter = new RecentCallsAdapter(getActivity(), cursorAllRows);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
list = (ListView) view.findViewById(R.id.listViewMain);
btnDelete = (Button) getActivity().findViewById(R.id.buttonDelete);
btnCreditRequest = (Button) getActivity().findViewById(R.id.buttonCr);
btnCreditBlock = (Button) getActivity().findViewById(R.id.buttonCRD);
list.setAdapter(adapter);
list.setOnItemClickListener(new ItemClickHandler()); //Add the inner ItemClickLister
btnSendTo = (Button) getActivity().findViewById(R.id.buttonSendTo);
btnSendTo.setOnClickListener(new DebugOnClick());//here I add the inner clicklister
return view;
}
/**
* Class that handles the one click action on the list
*/
public class ItemClickHandler implements AdapterView.OnItemClickListener{
//when there's one fast click, keep the selection on the item or remove it if already has it
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
int prevSelection = adapter.getSelectedIndex();
Toast.makeText(getActivity(), Integer.toString(selectedIndex), Toast.LENGTH_SHORT).show();
int newSelection = position;
if(prevSelection == position){
newSelection = -1;
}
selectedIndex = newSelection; //here I change the value of the global variable
adapter.setSelectedIndex(newSelection);
adapter.notifyDataSetChanged();
}
}
public class DebugOnClick implements View.OnClickListener{
public DebugOnClick(){
}
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), Integer.toString(selectedIndex), Toast.LENGTH_SHORT).show(); //here I show the value of the global variable and is always -1
}
}
}
Which may be the problem?
There is one possibility that comes into my mind. When you have an inner class instantiated it implicitly binds with an instance of the hosting class (as if it were a reference of the hosting class). So I assume that the inner classes that you use are each linked with a different instance of the hosted class and thus using a different selectedIndex. Your global variable is not really global, its an instance variable.
I just found the problem. The buttons are in the main activity, so I just moved the global variable to the main Activity and started to manipulate it from the fragments like this:
MainActivity ma = (MainActivity) getActivity();
ma.rcSelected = newSelection;
I'm attempting to use multiple enums that I've set as subclasses to a master class as the data source for listviews on separate fragments.
Each fragment will have two listviews, but each listview will only need to use certain parts of the data. Each enum has two strings "name" and "abbr" and a double "value".
I would like to set both strings as the ListView titles, and use the value in a calculation.
Listview1 will hold titles, abbrs, and one EditText in the center row. Listview2 will hold titles, abbrs, and one more TextView that will update based on the EditText input and the value from the enum. I realize I will need two custom adapters for this, one for the heterogeneous Listview1, and one for Listview2.
I am a little lost on implementing, and have only attempted doing the custom adapter for Listview2.
I have tried looking at multiple SO questions, and listview tutorials that use database models and then have tried to use that but with my static enum lists, but am just a bit lost. Any help from a high level approach, specifics, or a nice tutorial would be much appreciated. I am probably not even close on the right path as I am new at Android and relatively new at OOP, thanks for bearing with the poor code!
What I have so far (I set up a test project, which is why I have this listview inflated in main as opposed to in a fragment - if there are any issues with this besides switching the context let me know):
Enum class holding all enums
public class Enums {
public enum Pressures{
ITEM1 ("name", "abbr", 1.0),
etc...;
private final String name;
private final String abbr;
private final double value;
Pressures(String name, String abbr, double value) {
this.name = name;
this.abbr = abbr;
this.intermediary = intermediary;
}
public String getNames() {
return name;
}
public String getAbbr() {
return abbr;
}
public double getIntermediary() {
return intermediary;
}
}
public enum Enum2 {
...
}
}
Custom Adapter for Listview2:
public class CustomAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<Enums.Pressures> pressureEnum;
public CustomAdapter(Activity activity, List<Enums.Pressures> units) {
this.activity = activity;
this.pressureEnum = units;
}
#Override
public int getCount() {
return pressureEnum.size();
}
#Override
public Object getItem(int location) {
return pressureEnum.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_row, null);
TextView name = (TextView) convertView.findViewById(R.id.name);
TextView abbr = (TextView) convertView.findViewById(R.id.abbr);
Enums.Pressures p = pressureEnum.get(position);
name.setText(p.getNames());
abbr.setText(p.getAbbr());
return convertView;
}
}
Main:
public class Main extends Activity {
//This List was a poor attempt at setting the list from the enum
//I don't believe ArrayList is the proper choice as I have an enum object
//but I'm not quite sure what to use
private List<Enums.Pressures> pressureUnits = new ArrayList<Enums.Pressures>();
private ListView listView;
private CustomAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list);
adapter = new CustomAdapter(this, pressureUnits);
listView.setAdapter(adapter);
}
}
Your List "pressureUnits" is empty. You've specified that it is a list of Pressures but not added anything to it. Usually this is done with the "add" method, i.e. pressureUnits.add(...).
However what I think you want to use is Enums.Pressures.values(). This will return an array containing each of your enum elements. Then you will be able to create an adapter using that array. If you can't do it with the BaseAdapter you are using now, have a look at using the ArrayAdapter class rather than the BaseAdapter.
I want to use the "value" from the spinner.
When the user makes the choice i want to use that value in order to do some calculations.
My problem is :
1) How to get properly the value (item).I am using sth like "item.MyOnItemSelectedListener ==0".
2) What the value should be?For example ,above i have ==0 .This means the first choice from the spinner list?
The code:
public class number_cores extends Activity implements OnClickListener {
..
final Spinner spinner = (Spinner) findViewById(R.id.spinner);
...
public void onCreate(Bundle savedInstanceState) {
....
//spinner-drop_list
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.init_or_final, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new MyOnItemSelectedListener());
}
...
public void cores_func(){
...
double fcores=0;
MyOnItemSelectedListener obj=new MyOnItemSelectedListener();
if ( obj.getPosition()==0) fcores=initcores*Math.exp(-l*ttime);
else if (obj.getPosition()==1) fcores=initcores/Math.exp(-l*ttime);
..}
//spinner class
public class MyOnItemSelectedListener implements OnItemSelectedListener {
private int position;
public int getPosition() {return position;}
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
position=pos;
}
public void onNothingSelected(AdapterView <?> parent) {
// Do nothing.
}
}
Thanks!
Right now all you are doing is assigning the Object item the value of the selected item in the spinner. You aren't saving that value anywhere you can access it.
To fix this, in your OnItemSelectedListener save the selected value or position in a field. Access it through a getter method in your listener that returns the value. In the onItemSelected method you would set the value each time the user changes the spinner's value. In the Activity, access the saved value through the listener via the getter method.
Example:
If you wanted to get the position of the selected item, add private int position; and public int getPosition() {return position;} as a field and method (respectively) in the listener class, and in the onItemSelected method position = pos; to save the value. It is a similar idea to save the object if you want that. In your application, listenerName.getPosition() == 0 would be true if the first thing in the list was the selected item, so you can do logic with it.