I'm doing a calendar app, I wish to scroll my scrollview in the fragment to a specific Y-position as presenting the current time, I tried this code in an ACTIVITY, it succeeded, but it is not working in FRAGMENT. Can somebody please help me on this? Thanks.
This is the xml for fragement :
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="utar.fyp2.DayFragment">
<!-- TODO: Update blank fragment layout -->
<ScrollView
android:id="#+id/daySV"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/RLforall"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/datePickerLL"
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
</RelativeLayout>
<LinearLayout
android:id="#+id/timeLL"
android:layout_width="90dp"
android:layout_height="match_parent"
android:layout_marginTop="60dp"
android:orientation="vertical">
</LinearLayout>
<RelativeLayout
android:id="#+id/contentRL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="90dp"
android:layout_marginTop="60dp"/>
<Button
android:id="#+id/btntest"
android:text="click"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
</ScrollView>
This is the code:
public class DayFragment extends Fragment {
//declare element
private LinearLayout timeLL;
private RelativeLayout contentRL;
private RelativeLayout RLforall;
private ScrollView daySV;
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
// TODO: Rename and change types of parameters
private Integer mParam1;
private OnFragmentInteractionListener mListener;
public DayFragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static DayFragment newInstance(int param1) {
DayFragment fragment = new DayFragment();
Bundle args = new Bundle();
args.putInt(ARG_PARAM1, param1);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getInt(ARG_PARAM1);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_day,container,false);
timeLL = v.findViewById(R.id.timeLL);
contentRL = v.findViewById(R.id.contentRL);
GradientDrawable gradientDrawableForTime = new GradientDrawable();
gradientDrawableForTime.setStroke(1, Color.BLACK);
gradientDrawableForTime.setColor(Color.rgb(190,238,53));
GradientDrawable gradientDrawableForContent = new GradientDrawable();
gradientDrawableForContent.setStroke(1,Color.BLACK);
LinearLayout.LayoutParams matchParentLP = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
for (int i=0;i<24;i++)
{
//for time at left side
TextView tv = new TextView(getActivity());
tv.setText(""+i+":00");
tv.setHeight(120);
tv.setBackground(gradientDrawableForTime);
//tv.setBackgroundColor(Color.argb(55,55,5));
tv.setGravity(Gravity.CENTER);
timeLL.addView(tv);
//for line at right side
TextView tv2 = new TextView(getActivity());
tv2.setBackground(gradientDrawableForContent);
tv2.setLayoutParams(matchParentLP);
tv2.setY(i*120);
//tv2.setZ(1);
tv2.setHeight((int)(tv2.getY()+120));
tv2.setOnClickListener(new View.OnClickListener() {
//String eventid;
#Override
public void onClick(View view) {
//Toast.makeText(DayListActivity.this, key ,Toast.LENGTH_LONG).show();
Intent intent = new Intent(getActivity(), AddEventActivity.class);
startActivity(intent);
}
});
contentRL.addView(tv2);
}
RLforall = (RelativeLayout)v.findViewById(R.id.RLforall);
TextView line = new TextView(getActivity());
line.setHeight(5);
GradientDrawable gradientDrawableForLine = new GradientDrawable();
gradientDrawableForLine.setStroke(3,Color.BLACK);
line.setBackground(gradientDrawableForLine);
Calendar currentCalendar = Calendar.getInstance();
int h = currentCalendar.get(Calendar.HOUR_OF_DAY);
Double m = currentCalendar.get(Calendar.MINUTE)/60.0;
line.setY((int)(120 + ((h+m)*120)));
line.setLayoutParams(matchParentLP);
RLforall.addView(line);
**//this is where the setScrollY doesn't work**
daySV = v.findViewById(R.id.daySV);
daySV.setScrollY((int)(120 + ((h+m)*120)));
Toast.makeText(getActivity(),"donescoll",Toast.LENGTH_SHORT).show();
//daySV.scrollTo(0,(int)(120 + ((h+m)*120)));
//ignore this line below 1st
Button button = v.findViewById(R.id.btntest);
//button.setText(mParam1.toString());
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onButtonPressed(25);
}
});
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(int data) {
if (mListener != null) {
mListener.onFragmentInteraction(data);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(int data);
}
}
Related
I am trying to create a DialogFragment as
public class PlaceFragment extends DialogFragment {
public PlaceFragment() {
}
public static PlaceFragment newInstance() {
PlaceFragment placeFragment = new PlaceFragment();
Bundle args = new Bundle();
args.putDouble("Latitude", 12.3456);
placeFragment.setArguments(args);
return placeFragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_place, container, false);
AlertDialog.Builder placePicker = new AlertDialog.Builder(getContext());
placePicker.setView(R.layout.fragment_place)
.setTitle("Enter Latitude and Longitude")
.setPositiveButton("Ok", null);
// return inflater.inflate(R.layout.fragment_place, container);
return v;
}
}
which should be called as:
case R.id.action_geolocate:
FragmentManager fm = getSupportFragmentManager();
PlaceFragment placeFragment = PlaceFragment.newInstance();
placeFragment.show(fm, "");
return true;
But, as you can see, this is not working,as this is obviously showing the layout only, which is inflated. But I am trying to get the dialog with two line of EditText with Ok and Dissmiss button.
If I use a completely manual way, then I am getting the editText, but dont have any idea how to get those value with OkButton, like:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_place, container);
}
You can
Create a class extend DialogFragment
override and implement onCreateDialog to configure how the dialog appears. Here, create a Dialog / AlertDialog, can also populate its layout here.
In some cases, you want to implement onCreateView and handle views/actions there.
Hope this would help.
if I understand right, something like this should work:
public class DialogEnterExit extends DialogFragment {
public interface EnterExitDialogListener {
void onFinishEditDialog(String event, String place, Location location);
}
EnterExitDialogListener mListener;
private static final String TAG = DialogEnterExit.class.getSimpleName();
AppCompatDialog mDialog;
String mPlace;
Location mLocation;
public static DialogEnterExit newInstance(String place, Location location) {
DialogEnterExit f = new DialogEnterExit();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putString("PLACE", place);
args.putParcelable("LOCATION", location);
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPlace = getArguments().getString("PLACE");
mLocation = getArguments().getParcelable("LOCATION");
}
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater layoutInflater = getActivity().getLayoutInflater();
View view = layoutInflater.inflate(R.layout.layout_enter_exit_dialog,null);
final RadioButton enter = view.findViewById(R.id.radio_enter);
final RadioButton exit = view.findViewById(R.id.radio_exit);
TextView place = view.findViewById(R.id.place_picked);
place.setText(mPlace);
enter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mListener != null) {
mListener.onFinishEditDialog(getString(R.string.dialog_transition_entered), mPlace,
mLocation);
}
mDialog.dismiss();
}
});
exit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mListener != null) {
mListener.onFinishEditDialog(getString(R.string.dialog_transition_exited), mPlace,
mLocation);
}
mDialog.dismiss();
}
});
builder
.setView(view)
.setTitle(getString(R.string.dialog_title_event))
.setCancelable(true);
mDialog = builder.create();
return mDialog;
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
// Verify that the host activity implements the callback interface
try {
// Instantiate the EditNameDialogListener so we can send events to the
host
mListener = (EnterExitDialogListener) context;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(context.toString()
+ " must implement EnterExitDialogListener" );
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
and the view in xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="place:"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/place_picked"
android:hint="place name"
android:layout_weight="3"/>
</LinearLayout>
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/radio_enter"
android:text="#string/geofence_transition_entered"/>
<RadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/radio_exit"
android:text="#string/geofence_transition_exited"/>
</LinearLayout>
</LinearLayout>
and to use:
android.location.Location loc = new android.location.Location("");
loc.setLatitude(location.getLatitude());
loc.setLongitude(location.getLongitude());
DialogEnterExit dialogEnterExit = DialogEnterExit.newInstance(location.getName(), loc);
getSupportFragmentManager().beginTransaction()
.add(dialogEnterExit, "enter exit dialog").commitAllowingStateLoss();
i think you should implement
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
instead of
#Override
public View onCreateView(Bundle savedInstanceState) {
and return a dialog instead of view and i think it would be better if you do not leave the tag string in .show(ft,"") empty
I have an Activity which loads a Fragment using getFragmentManager() . The fragment is working perfecty until an android notification appears. After that, the fragment becomes empty.
This is my application after the activity has loaded the fragment. The red square is the fragment.
Here, a external notification arrives to the mobile:
Only the fragment becomes empty:
Here my Activity:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, FragmentSettings.OnFragmentInteractionListener{
FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (fragmentManager == null) {
fragmentManager = getSupportFragmentManager();
}
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
if (id == R.id.nav_locker_room) {
fragmentNameSection = "FragmentLockerRoom";
fragment = FragmentLockerRoom.newInstance(user, "");
}
fragmentManager.beginTransaction().replace(R.id.flContent, fragment, fragmentNameSection).commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
}
#Override
public void onResume() {
super.onResume();
}
}
Here the activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#drawable/side_nav_menu"
app:itemTextColor="#android:color/white"
app:itemIconTint="#android:color/white"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
And finally this is my Fragment:
public class FragmentSettings extends Fragment {
private static final String ARG_USER = "user";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
getUser user;
View v;
DatabaseManager db;
private OnFragmentInteractionListener mListener;
ToggleButton notificationTrain, notificationNextMatch, liveSounds;
LayoutInflater inflater;
ViewGroup container;
FragmentSettings fragmentSettings;
public FragmentSettings() {
}
public static FragmentSettings newInstance(getUser user, String param2) {
FragmentSettings fragment = new FragmentSettings();
Bundle args = new Bundle();
args.putSerializable(ARG_USER, user);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
user = (com.androidsrc.futbolin.communications.http.auth.get.getUser) getArguments().getSerializable(ARG_USER);
mParam2 = getArguments().getString(ARG_PARAM2);
}
this.fragmentSettings = this;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
this.inflater = inflater;
this.container = container;
buildLayout();
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
public void buildLayout(){
db = new DatabaseManager(getActivity());
v = inflater.inflate(R.layout.fragment_fragment_settings, container, false);
notificationTrain = v.findViewById(R.id.fragment_settings_notification_trainment_toggle);
notificationNextMatch = v.findViewById(R.id.fragment_settings_notification_next_match_toggle);
liveSounds = v.findViewById(R.id.fragment_settings_notification_live_sounds_toggle);
notificationTrain.setChecked(db.findNotification().isTrainActive());
notificationNextMatch.setChecked(db.findNotification().isMatchActive());
liveSounds.setChecked(db.findNotification().isLiveSoundsActive());
Log.e("notif",db.findNotification().toString());
notificationTrain.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) {
if(db == null){
db = new DatabaseManager(getActivity());
}
Notification notification = db.findNotification();
notification.setTrainActive(isChecked);
db.saveNotification(notification);
}
}) ;
notificationNextMatch.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) {
if(db == null){
db = new DatabaseManager(getActivity());
}
Notification notification = db.findNotification();
notification.setMatchActive(isChecked);
db.saveNotification(notification);
}
}) ;
liveSounds.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked) {
if(db == null){
db = new DatabaseManager(getActivity());
}
Notification notification = db.findNotification();
notification.setLiveSoundsActive(isChecked);
db.saveNotification(notification);
}
}) ;
}
}
And the layout of my Fragment is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ScrollView
android:id="#+id/fragment_locker_room_scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="60dp"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/fragment_locker_room_total_constraint_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<!--
REST OF VIEWS
-->
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</LinearLayout>
Finally I found the solution. And ScrollView that has a layout_height="match_parent" when a notification is received changes his layout_height to 0.
Changing layout_height="match_parent" to layout_height="wrap_content" in ScrollView solves the issue.
I'm following the "developping android apps" course in Udacity and when I run the app (sunshine app for wheather) in a handset emulator, when I click on an item from the forecast list, it must show the details of the selected item, but the app crashes and it show the following error: "ScrollView can host only one direct child" you can see that my scrollview has only one child
here are the codes of the mainactivity, detailactivity, and the fragments:
(I removed importations)
MainActivity
public class MainActivity extends AppCompatActivity implements ForecastFragment.Callback{
private final String LOG_TAG = MainActivity.class.getSimpleName();
private final String FORECASTFRAGMENT_TAG = "FFTAG";
private static final String DETAILFRAGMENT_TAG = "DFTAG";
private String mLocation;
boolean mTwoPane;
#Override
protected void onCreate(Bundle savedInstanceState) {
mLocation = Utility.getPreferredLocation(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.weather_detail_container) != null) {
// The detail container view will be present only in the large-screen layouts
// (res/layout-sw600dp). If this view is present, then the activity should be
// in two-pane mode.
mTwoPane = true;
// In two-pane mode, show the detail view in this activity by
// adding or replacing the detail fragment using a
// fragment transaction.
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.weather_detail_container, new DetailFragment(), DETAILFRAGMENT_TAG)
.commit();
}
} else {
mTwoPane = false;
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
#Override
protected void onResume() {
super.onResume();
String location = Utility.getPreferredLocation( this );
// update the location in our second pane using the fragment manager
if (location != null && !location.equals(mLocation)) {
ForecastFragment ff = (ForecastFragment)getSupportFragmentManager().findFragmentById(R.id.fragment_forecast);
if ( null != ff ) {
ff.onLocationChanged();
}
DetailFragment df = (DetailFragment)getSupportFragmentManager().findFragmentByTag(DETAILFRAGMENT_TAG);
if ( null != df ) {
df.onLocationChanged(location);
}
mLocation = location;
}
}
#Override
public void onItemSelected(Uri contentUri) {
if (mTwoPane) {
// In two-pane mode, show the detail view in this activity by
// adding or replacing the detail fragment using a
// fragment transaction.
Bundle args = new Bundle();
args.putParcelable(DetailFragment.DETAIL_URI, contentUri);
DetailFragment fragment = new DetailFragment();
fragment.setArguments(args);
getSupportFragmentManager().beginTransaction()
.replace(R.id.weather_detail_container, fragment, DETAILFRAGMENT_TAG)
.commit();
} else {
Intent intent = new Intent(this, DetailActivity.class)
.setData(contentUri);
startActivity(intent);
}
}
}
ForecastFragment
public class ForecastFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
private static final int FORECAST_LOADER = 0;
// For the forecast view we're showing only a small subset of the stored data.
// Specify the columns we need.
private static final String[] FORECAST_COLUMNS = {
// In this case the id needs to be fully qualified with a table name, since
// the content provider joins the location & weather tables in the background
// (both have an _id column)
// On the one hand, that's annoying. On the other, you can search the weather table
// using the location set by the user, which is only in the Location table.
// So the convenience is worth it.
WeatherContract.WeatherEntry.TABLE_NAME + "." + WeatherContract.WeatherEntry._ID,
WeatherContract.WeatherEntry.COLUMN_DATE,
WeatherContract.WeatherEntry.COLUMN_SHORT_DESC,
WeatherContract.WeatherEntry.COLUMN_MAX_TEMP,
WeatherContract.WeatherEntry.COLUMN_MIN_TEMP,
WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING,
WeatherContract.WeatherEntry.COLUMN_WEATHER_ID,
WeatherContract.LocationEntry.COLUMN_COORD_LAT,
WeatherContract.LocationEntry.COLUMN_COORD_LONG
};
// These indices are tied to FORECAST_COLUMNS. If FORECAST_COLUMNS changes, these
// must change.
static final int COL_WEATHER_ID = 0;
static final int COL_WEATHER_DATE = 1;
static final int COL_WEATHER_DESC = 2;
static final int COL_WEATHER_MAX_TEMP = 3;
static final int COL_WEATHER_MIN_TEMP = 4;
static final int COL_LOCATION_SETTING = 5;
static final int COL_WEATHER_CONDITION_ID = 6;
static final int COL_COORD_LAT = 7;
static final int COL_COORD_LONG = 8;
private ForecastAdapter mForecastAdapter;
public interface Callback {
/**
* DetailFragmentCallback for when an item has been selected.
*/
public void onItemSelected(Uri dateUri);
}
public ForecastFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add this line in order for this fragment to handle menu events.
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.forecastfragment, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_refresh) {
updateWeather();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// The CursorAdapter will take data from our cursor and populate the ListView.
mForecastAdapter = new ForecastAdapter(getActivity(), null, 0);
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
// Get a reference to the ListView, and attach this adapter to it.
ListView listView = (ListView) rootView.findViewById(R.id.listview_forecast);
listView.setAdapter(mForecastAdapter);
// We'll call our MainActivity
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
// CursorAdapter returns a cursor at the correct position for getItem(), or null
// if it cannot seek to that position.
Cursor cursor = (Cursor) adapterView.getItemAtPosition(position);
if (cursor != null) {
String locationSetting = Utility.getPreferredLocation(getActivity());
((Callback) getActivity())
.onItemSelected(WeatherContract.WeatherEntry.buildWeatherLocationWithDate(
locationSetting, cursor.getLong(COL_WEATHER_DATE)
));
}
}
});
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
getLoaderManager().initLoader(FORECAST_LOADER, null, this);
super.onActivityCreated(savedInstanceState);
}
// since we read the location when we create the loader, all we need to do is restart things
void onLocationChanged( ) {
updateWeather();
getLoaderManager().restartLoader(FORECAST_LOADER, null, this);
}
private void updateWeather() {
FetchWeatherTask weatherTask = new FetchWeatherTask(getActivity());
String location = Utility.getPreferredLocation(getActivity());
weatherTask.execute(location);
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
String locationSetting = Utility.getPreferredLocation(getActivity());
// Sort order: Ascending, by date.
String sortOrder = WeatherContract.WeatherEntry.COLUMN_DATE + " ASC";
Uri weatherForLocationUri = WeatherContract.WeatherEntry.buildWeatherLocationWithStartDate(
locationSetting, System.currentTimeMillis());
return new CursorLoader(getActivity(),
weatherForLocationUri,
FORECAST_COLUMNS,
null,
null,
sortOrder);
}
#Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
mForecastAdapter.swapCursor(cursor);
}
#Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
mForecastAdapter.swapCursor(null);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.bassem.sunshine.app.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
content_main.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment"
android:name="com.example.bassem.sunshine.app.ForecastFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:layout="#layout/fragment_main" />
fragment_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".ForecastFragment"
tools:showIn="#layout/activity_main">
<ListView
style="#style/ForecastListStyle"
android:id="#+id/listview_forecast"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
DetailActivity
public class DetailActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
if (savedInstanceState == null) {
Bundle arguments = new Bundle();
arguments.putParcelable(DetailFragment.DETAIL_URI, getIntent().getData());
DetailFragment fragment = new DetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.weather_detail_container, fragment)
.commit();
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.detail, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
startActivity(new Intent(this, SettingsActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
}
DetailFragment
public class DetailFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
private static final String LOG_TAG = DetailFragment.class.getSimpleName();
static final String DETAIL_URI = "URI";
private static final String FORECAST_SHARE_HASHTAG = " #SunshineApp";
private ShareActionProvider mShareActionProvider;
private String mForecast;
private Uri mUri;
private static final int DETAIL_LOADER = 0;
private static final String[] DETAIL_COLUMNS = {
WeatherEntry.TABLE_NAME + "." + WeatherEntry._ID,
WeatherEntry.COLUMN_DATE,
WeatherEntry.COLUMN_SHORT_DESC,
WeatherEntry.COLUMN_MAX_TEMP,
WeatherEntry.COLUMN_MIN_TEMP,
WeatherEntry.COLUMN_HUMIDITY,
WeatherEntry.COLUMN_PRESSURE,
WeatherEntry.COLUMN_WIND_SPEED,
WeatherEntry.COLUMN_DEGREES,
WeatherEntry.COLUMN_WEATHER_ID,
// This works because the WeatherProvider returns location data joined with
// weather data, even though they're stored in two different tables.
WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING
};
// These indices are tied to DETAIL_COLUMNS. If DETAIL_COLUMNS changes, these
// must change.
public static final int COL_WEATHER_ID = 0;
public static final int COL_WEATHER_DATE = 1;
public static final int COL_WEATHER_DESC = 2;
public static final int COL_WEATHER_MAX_TEMP = 3;
public static final int COL_WEATHER_MIN_TEMP = 4;
public static final int COL_WEATHER_HUMIDITY = 5;
public static final int COL_WEATHER_PRESSURE = 6;
public static final int COL_WEATHER_WIND_SPEED = 7;
public static final int COL_WEATHER_DEGREES = 8;
public static final int COL_WEATHER_CONDITION_ID = 9;
private ImageView mIconView;
private TextView mFriendlyDateView;
private TextView mDateView;
private TextView mDescriptionView;
private TextView mHighTempView;
private TextView mLowTempView;
private TextView mHumidityView;
private TextView mWindView;
private TextView mPressureView;
public DetailFragment() {
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle arguments = getArguments();
if (arguments != null) {
mUri = arguments.getParcelable(DetailFragment.DETAIL_URI);
}
View rootView = inflater.inflate(R.layout.fragment_detail, container, false);
mIconView = (ImageView) rootView.findViewById(R.id.detail_icon);
mDateView = (TextView) rootView.findViewById(R.id.detail_date_textview);
mFriendlyDateView = (TextView) rootView.findViewById(R.id.detail_day_textview);
mDescriptionView = (TextView) rootView.findViewById(R.id.detail_forecast_textview);
mHighTempView = (TextView) rootView.findViewById(R.id.detail_high_textview);
mLowTempView = (TextView) rootView.findViewById(R.id.detail_low_textview);
mHumidityView = (TextView) rootView.findViewById(R.id.detail_humidity_textview);
mWindView = (TextView) rootView.findViewById(R.id.detail_wind_textview);
mPressureView = (TextView) rootView.findViewById(R.id.detail_pressure_textview);
return rootView;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.detailfragment, menu);
// Retrieve the share menu item
MenuItem menuItem = menu.findItem(R.id.action_share);
// Get the provider and hold onto it to set/change the share intent.
mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(menuItem);
// If onLoadFinished happens before this, we can go ahead and set the share intent now.
if (mForecast != null) {
mShareActionProvider.setShareIntent(createShareForecastIntent());
}
}
private Intent createShareForecastIntent() {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, mForecast + FORECAST_SHARE_HASHTAG);
return shareIntent;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
getLoaderManager().initLoader(DETAIL_LOADER, null, this);
super.onActivityCreated(savedInstanceState);
}
void onLocationChanged( String newLocation ) {
// replace the uri, since the location has changed
Uri uri = mUri;
if (null != uri) {
long date = WeatherContract.WeatherEntry.getDateFromUri(uri);
Uri updatedUri = WeatherContract.WeatherEntry.buildWeatherLocationWithDate(newLocation, date);
mUri = updatedUri;
getLoaderManager().restartLoader(DETAIL_LOADER, null, this);
}
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
if ( null != mUri ) {
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
return new CursorLoader(
getActivity(),
mUri,
DETAIL_COLUMNS,
null,
null,
null
);
}
return null;
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (data != null && data.moveToFirst()) {
// Read weather condition ID from cursor
int weatherId = data.getInt(COL_WEATHER_CONDITION_ID);
// Use placeholder Image
mIconView.setImageResource(Utility.getArtResourceForWeatherCondition(weatherId));
// Read date from cursor and update views for day of week and date
long date = data.getLong(COL_WEATHER_DATE);
String friendlyDateText = Utility.getDayName(getActivity(), date);
String dateText = Utility.getFormattedMonthDay(getActivity(), date);
mFriendlyDateView.setText(friendlyDateText);
mDateView.setText(dateText);
// Read description from cursor and update view
String description = data.getString(COL_WEATHER_DESC);
mDescriptionView.setText(description);
// Read high temperature from cursor and update view
boolean isMetric = Utility.isMetric(getActivity());
double high = data.getDouble(COL_WEATHER_MAX_TEMP);
String highString = Utility.formatTemperature(getActivity(), high, isMetric);
mHighTempView.setText(highString);
// Read low temperature from cursor and update view
double low = data.getDouble(COL_WEATHER_MIN_TEMP);
String lowString = Utility.formatTemperature(getActivity(), low, isMetric);
mLowTempView.setText(lowString);
// Read humidity from cursor and update view
float humidity = data.getFloat(COL_WEATHER_HUMIDITY);
mHumidityView.setText(getActivity().getString(R.string.format_humidity, humidity));
// Read wind speed and direction from cursor and update view
float windSpeedStr = data.getFloat(COL_WEATHER_WIND_SPEED);
float windDirStr = data.getFloat(COL_WEATHER_DEGREES);
mWindView.setText(Utility.getFormattedWind(getActivity(), windSpeedStr, windDirStr));
// Read pressure from cursor and update view
float pressure = data.getFloat(COL_WEATHER_PRESSURE);
mPressureView.setText(getActivity().getString(R.string.format_pressure, pressure));
mForecast = String.format("%s - %s - %s/%s", dateText, description, high, low);
if (mShareActionProvider != null) { mShareActionProvider.setShareIntent(createShareForecastIntent());
}
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) { }
}
activity_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.bassem.sunshine.app.DetailActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_detail" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
content_detail.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/weather_detail_container"
android:name="com.example.bassem.sunshine.app.DetailFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:layout="#layout/fragment_detail" />
fragment_detail.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="#+id/detail_day_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/detail_date_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/detail_high_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/detail_low_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:id="#+id/detail_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/detail_forecast_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="#+id/detail_humidity_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/detail_wind_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/detail_pressure_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
Probably an error when generating R. Try cleaning then rebuild. If that doesn't work, I'd suggest copying the whole fragment_detail.xml and create a new xml file to paste it there. Delete the old one of course, then clean and rebuild.
I have an activity that hosts a fragment. The activity essentially has no content except a spinner that indicates the fragment is loading. The fragment is dependent upon a stable internet connection, therefore the length of time required for the spinner to be visible is dynamic in nature.
I want to remove the spinner on the activity after the fragment successfully loads. I tried using the isAdded() method, however that approach did not work. Any help is appreciated:
Fragment:
public class LatestFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private RecyclerView mRecyclerViewForLatestPolls;
private RecyclerView.Adapter mLatestAdapter;
private ArrayList<LatestPoll> mLatestPollsArray;
private DateFormat mDateFormat;
private Date mDate;
private String mCurrentDateString;
private Firebase mBaseRef;
private Firebase mPollRef;
private Firebase mUpdateRef;
private FragmentListener mFragmentListener;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public LatestFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment LatestFragment.
*/
// TODO: Rename and change types and number of parameters
public static LatestFragment newInstance(String param1, String param2) {
LatestFragment fragment = new LatestFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDateFormat = new SimpleDateFormat("MM-dd-yyyy");
mDate = new Date();
mCurrentDateString = mDateFormat.format(mDate);
mBaseRef = FirebaseUtil.FIREBASE;
mPollRef = mBaseRef.child("Polls");
mUpdateRef = mPollRef.child(mCurrentDateString);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_latest, container, false);
getActivity().setTitle(R.string.latest_title);
mRecyclerViewForLatestPolls = (RecyclerView) rootView.findViewById(R.id.latest_RecyclerView);
mLatestPollsArray = new ArrayList<>();
mLatestAdapter = new MyAdapter(mLatestPollsArray);
LinearLayoutManager llm = new LinearLayoutManager(getActivity().getApplicationContext());
llm.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerViewForLatestPolls.setLayoutManager(llm);
mRecyclerViewForLatestPolls.setItemAnimator(new SlideInLeftAnimator());
mRecyclerViewForLatestPolls.setAdapter(new AlphaInAnimationAdapter(mLatestAdapter));
mUpdateRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int numberOfPollsForDay = (int) dataSnapshot.getChildrenCount();
for (int i = 0; i < numberOfPollsForDay; i++) {
String latestPollQuestion = (String) dataSnapshot.child(String.valueOf(i + 1)).child("Poll_Question").getValue();
String pollImageURL = (String) dataSnapshot.child(String.valueOf(i + 1)).child("Image").getValue();
mLatestPollsArray.add(0, new LatestPoll(latestPollQuestion, pollImageURL));
mLatestAdapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
// Inflate the layout for this fragment
return rootView;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
// Force the parent activity to implement listener.
if (context instanceof FragmentListener) {
mFragmentListener = (FragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
mFragmentListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<LatestPoll> mDataSet;
int lastPosition = -1;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
protected TextView pollQuestion;
protected ImageView pollImage;
public ViewHolder(View v) {
super(v);
pollQuestion = (TextView) v.findViewById(R.id.latest_item_question);
pollImage = (ImageView) v.findViewById(R.id.pollThumbNailImage);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(ArrayList<LatestPoll> myDataset) {
mDataSet = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.latest_item, parent, false);
// set the view's size, margins, paddings and layout parameters
return new ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
//The OutOfBoundsException is pointing here
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Log.v("ON_BIND", "ON_BINDVIEWHOLDER CALLED");
LatestPoll latestPoll = mDataSet.get(position);
holder.pollQuestion.setText(latestPoll.getQuestion());
Picasso.with(getActivity())
.load(latestPoll.getPollImage())
.fit()
.placeholder(R.drawable.loading_spinnter_white)
.into(holder.pollImage);
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataSet.size();
}
}
private void onLoad() {
if (mFragmentListener != null) {
mFragmentListener.onFragmentLoaded();
}
}
public interface FragmentListener {
void onFragmentLoaded();
}
}
Activity XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/action_tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/black"
android:titleTextColor="#color/white">
</android.support.v7.widget.Toolbar>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="#+id/pbHeaderProgress"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:progressDrawable="#drawable/loading_spinnter_white">
</ProgressBar>
<TextView
android:id="#+id/progress_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/pbHeaderProgress"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:text="#string/loading_poll_data"
android:textColor="#color/white"
android:textSize="24sp" />
</RelativeLayout>
<FrameLayout
android:id="#+id/latest_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</FrameLayout>
</LinearLayout>
<!-- The navigation drawer -->
<ListView
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#111"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp" />
Image:
In fragment create a listener interface,
private MyFragmentListener mListener;
/**
* onLoad should be called when the fragment has loaded.
*/
private void onLoad() {
if (mListener != null) {
mListener.onFragmentLoaded();
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
// Force the parent activity to implement listener.
if (context instanceof MyFragmentListener) {
mListener = (MyFragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface MyFragmentListener {
void onFragmentLoaded();
}
Then in parent activity,
public class MainActivity extends Activity implements MyFragment.MyFragmentListener{
#Override
public void onFragmentLoad() {
// HIDE the progressbar spinner.
}
See Communicating with Other Fragments for more info.
I am trying to add the same class several times to a viewpager to show different info which is read from a sqlite DB. The thing is when the view is created, always override the objects, textviews etc..., in the current view and not in the fragment for each page.
names = new ArrayList<String>();
for (int d : descritions) {
Description temp = DBCompanies.getDescriptionById(db_path,
GSSettings.DBCODE, d, Locale.getDefault().getLanguage(),
GSSettings.DEFAULTLANGUAGE, false);
names.add(temp.getTitle());
}
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// mViewPager.setCurrentItem(0);
mViewPager.refreshDrawableState();
...
How can I avoid this behavior?
thanks.
EDIT:
I added more code to clarify my question:
framecompany100.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ly_main"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbarDefaultDelayBeforeFade="500"
android:scrollbarFadeDuration="200"
android:scrollbarThumbVertical="#drawable/scrollbar_vertical_thumb_company" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<Gallery
android:id="#+id/ga_image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp" />
<RelativeLayout
android:id="#+id/ly_details"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/ga_image" >
<ImageView
android:id="#+id/iv_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_margin="5dp"
android:src="#drawable/ic_button_options" />
<RelativeLayout
android:id="#+id/ly_details_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:layout_toRightOf="#+id/iv_options"
android:background="#77ffffff" >
<TextView
android:id="#+id/tv_address" android:text="kldfjhskdjhfksj"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textSize="15sp" />
</RelativeLayout>
</RelativeLayout>
<TextView
android:id="#+id/tv_description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/ly_details"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:textSize="15sp"
android:textStyle="bold" />
</RelativeLayout>
and the class for this layout:
FrameCompany100.java
public class FrameCompany100 extends Fragment implements OnClickListener,
PictureUpdater, FragmentName {
private Bundle data = new Bundle();
private Gallery image;
private Description description;
private BaseAdapter adapter;
private String db_path;
private GuiParams main_params;
private Company company;
private String name = "";
#Override
public void onCreate(Bundle savedInstanceState) {
data = this.getArguments();
if (savedInstanceState != null)
data = savedInstanceState;
db_path = "/data/data/" + getActivity().getPackageName()
+ GSSettings.DB_PATH;
description = DBCompanies.getDescriptionById(db_path,
GSSettings.DBCODE, data.getInt("descriptionId"), Locale
.getDefault().getLanguage(), "es", false);
company = DBCompanies.getCompany(db_path, GSSettings.DBCODE,
description.getCompanyId());
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.framecompany100, container, false);
}
void init() {
try {
Display display = getActivity().getWindowManager()
.getDefaultDisplay();
int height = display.getHeight();
final int width = display.getWidth();
// params
main_params = DBCompanies.getGuiParams(db_path, GSSettings.DBCODE,
description.getCompanyId(), GSSettings.body);
if (main_params == null || main_params.getBackgroundcolor() == null
|| main_params.getBackgroundcolor().equals("")
|| main_params.getTextcolor() == null
|| main_params.getTextcolor().equals(""))
main_params = DBApp.getGuiParam(db_path, GSSettings.DBCODE,
GSSettings.body);
// main Layout
RelativeLayout ly_main = (RelativeLayout) getActivity()
.findViewById(R.id.ly_main);
try {
ly_main.setBackgroundColor(Color.parseColor(main_params
.getBackgroundcolor()));
} catch (Exception e) {
}
Typeface font_body = null;
try {
font_body = Typeface.createFromAsset(getActivity().getAssets(),
"fonts/" + main_params.getFont());
} catch (Exception e) {
font_body = Typeface.createFromAsset(
getActivity().getAssets(),
"fonts/"
+ DBApp.getGuiParam(db_path, GSSettings.DBCODE,
GSSettings.body).getFont());
}
TextView tv_description = (TextView) getActivity().findViewById(
R.id.tv_description);
try {
tv_description.setTextColor(Color.parseColor(main_params
.getTextcolor()));
} catch (Exception e) {
}
if (description == null) {
tv_description.setText(R.string.nodescription);
} else {
tv_description.setText(description.getText());
}
TextView tv_address = (TextView) getActivity().findViewById(
R.id.tv_address);
try {
tv_address.setTextColor(Color.parseColor(main_params
.getTextcolor()));
} catch (Exception e) {
}
.....
}
#Override
public void onResume() {
init();
// ((MainLayout) getActivity()).setDescription(description);
super.onResume();
}
the FragmentPagerAdapter
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Description temp = DBCompanies.getDescriptionById(db_path,
GSSettings.DBCODE, descritions[i], Locale.getDefault()
.getLanguage(), GSSettings.DEFAULTLANGUAGE, false);
Fragment fragment = null;
try {
fragment = new CompanyLayout100();
((FragmentName) fragment).setName(temp.getTitle());
Bundle bundle = new Bundle();
bundle.putInt("descriptionId", temp.getId());
fragment.setArguments(bundle);
} catch (Exception e) {
}
return fragment;
}
#Override
public int getCount() {
return descritions.length;
// return fragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
String name = "";
try {
name = names.get(position);
} catch (Exception e) {
}
return name;
}
}
what's happening is, the viewpager create the view for these frames but always is entering the data in the visible frame. I think is because the layout.xml is the same so there is only one id and all object are pointing at the visible layout.
You need a FragmentPagerAdapter that creates the instance ...
public class PagerAdapter extends FragmentPagerAdapter {
int pages;
public PagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public int getCount() {
return pages;
}
#Override
public Fragment getItem(int position) {
return MyFragment.newInstance(position);
}
public void setPages(int no) {
pages = no;
}
}
So in the main activity you attach the PagerAdapter ...
adapter = new PagerAdapter(getSupportFragmentManager());
adapter.setPages(noPages);
pager.setAdapter(adapter);
Finally you need your Fragment including the newInstance method. Check out this http://android-developers.blogspot.de/2011/08/horizontal-view-swiping-with-viewpager.html for more.
Cheers!
Edit #1: MyFragment; note: it is essential to pass the position as an argument
public class MyFragment extends SherlockFragment {
private static final String KEY_POSITION="position";
static MyFragment newInstance(int position) {
MyFragment frag=new MyFragment();
Bundle args=new Bundle();
args.putInt(KEY_POSITION, position);
frag.setArguments(args);
return(frag);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View result=inflater.inflate(R.layout.editor, container, false);
EditText editor=(EditText)result.findViewById(R.id.editor);
int position=getArguments().getInt(KEY_POSITION, -1);
editor.setHint(String.format(getString(R.string.hint), position + 1));
return(result);
}
}