I am passing the position of the RecyclerView from first FirstFragment to SecondFragment and it works. After scrolling in that one, I get the position again and I am passing it to the FirstFragment. But, when FirstFragment gets the position, the list is not scrolled to that particular index.
FirstFragment
public class FirstFragment extends BaseFragment implements FirstAdapter.OnItemInteractionListener {
FragmentFirstBinding mBinder;
List<MyItem> mMyItemList;
GridLayoutManager mManager;
MyItem mMyItem;
FirstAdapter mAdapter;
int mPosition;
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
public static final String GET_SECOND_FRAGMENT = "get_second_fragment";
public static FirstFragment newInstance() {
FirstFragment fragment = new FirstFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMyItemList = new ArrayList<>();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mBinder = DataBindingUtil.inflate(inflater, R.layout.fragment_first, container, false);
populate();
mManager = new GridLayoutManager(getContext(), 3, GridLayoutManager.VERTICAL, false);
mAdapter = new FirstAdapter(getContext(), mMyItemList);
mBinder.rvFirst.setLayoutManager(mManager);
mBinder.rvFirst.setAdapter(mAdapter);
mAdapter.addOnItemInteractionListener(this);
EventBus.getDefault().register(this);
return mBinder.getRoot();
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onDestroyView() {
super.onDestroyView();
EventBus.getDefault().unregister(this);
}
private void populate() {
for (int i = 0; i < 30; i++) {
mMyItemList.add(i, mMyItem);
}
}
private void sendAction(String action, List<MyItem> myItemList, int position) {
if (mListener == null) {
return;
}
Bundle bundle = new Bundle();
bundle.putString(Constants.ACTION, action);
bundle.putParcelable(Constants.DATA1, Parcels.wrap(myItemList));
bundle.putInt(Constants.POSITION, position);
mListener.onFragmentInteraction(bundle);
}
#Override
public void onItemClick(int position) {
sendAction(GET_SECOND_FRAGMENT, mMyItemList, position);
}
#Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onMessage(SendPos event) {
mPosition = event.getPos();
mBinder.rvFirst.scrollToPosition(mPosition);
mBinder.rvFirst.getLayoutManager().scrollToPosition(mPosition);
EventBus.getDefault().removeStickyEvent(event);
}
}
Second Fragment
public class SecondFragment extends BaseFragment {
FragmentSecondBinding mBinder;
List<MyItem> mMyItemList;
LinearLayoutManager mManager;
Parcelable mParcelable;
SecondAdapter mAdapter;
int mPosition;
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
public static final String ACTION_BACK = "back";
public static SecondFragment newInstance(List<MyItem> myItemList, int position) {
SecondFragment fragment = new SecondFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_PARAM1, Parcels.wrap(myItemList));
args.putInt(ARG_PARAM2, position);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParcelable = getArguments().getParcelable(ARG_PARAM1);
mMyItemList = Parcels.unwrap(mParcelable);
mPosition = getArguments().getInt(ARG_PARAM2);
}
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mBinder = DataBindingUtil.inflate(inflater, R.layout.fragment_second, container, false);
mManager = new LinearLayoutManager(getContext());
mAdapter = new SecondAdapter(getContext(), mMyItemList);
mBinder.rvSecond.setLayoutManager(mManager);
mBinder.rvSecond.setAdapter(mAdapter);
mManager.scrollToPosition(mPosition);
setUIListeners();
return mBinder.getRoot();
}
private void setUIListeners() {
mBinder.back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mPosition = mManager.findFirstVisibleItemPosition();
sendPos(mPosition);
sendActionToActivity(ACTION_BACK);
}
});
}
private void sendActionToActivity(String action) {
Bundle bundle = new Bundle();
bundle.putString(Constants.ACTION, action);
mListener.onFragmentInteraction(bundle);
}
private void sendPos(int pos) {
SendPos sendPos = new SendPos();
sendPos.setPos(pos);
EventBus.getDefault().postSticky(sendPos);
}
}
Have you try to use the RecyclerView as well ? for example :
mRecyclerView.scrollToPosition(mPosition);
mRecyclerView.getLayoutManager().scrollToPosition(mPosition);
Don't forget to register the EventBus : EventBus.getDefault().register(this);
EDIT:
You can use RecyclerView.smoothScrollToPosition(int position) instead
Hope this helps.
Sorry for my english.
Related
As showing in the above picture, I have created a Fragment named CustomerFragLogin with the code as follows :-
public class customerFragLogin extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
public customerFragLogin() {
// Required empty public constructor
}
public static customerFragLogin newInstance(String param1, String param2) {
customerFragLogin fragment = new customerFragLogin();
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);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.frag_customer_login, container, false);
}
}
Now, when I click on 'Login' button or 'Forget password' textview I want to open a new activity. How do I implement this ?
add this to your CustomerFragLogin
#Override
public void onViewCreated(#NotNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TextView textView= findViewById(R.id.textView)
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(getActivity(), NewActivity.class));
}
});
}
make sure your activity is declared in the manifest
I have 3 bottom navigation tabs in my application :
Home
MyTour
Profile
In MyTour, I am using MyTourFragment which have 3 different tabs :
Pending(0)
Success(1)
Failed(2)
For all three tabs(Pending, Success, Failed) I am using FragmentMyTourJobList and depend on condition I am showing pending or success or failed data in all three tabs.
Problem statement :
When I click on MyTour Navigation Item, Pending Fragment instance is coming null and I am only able to see blank fragment but if i click to success or failed then I can see data. Pending tab data is only visible after coming back from other tabs but not initially.
Here is MyTourFragment code :
public class MyTourFragment {
public MyTourFragment() {
}
public static MyTourFragment newInstance(MyTourFragmentListener myTourFragmentListener) {
return new MyTourFragment(myTourFragmentListener);
}
private MyTourFragment(MyTourFragmentListener myTourFragmentListener) {
this.mMyTourFragmentListener = myTourFragmentListener;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewModel.setNavigator(this);
setHasOptionsMenu(true);
//Get the Tab Id.
Bundle bundle = this.getArguments();
if (bundle != null) {
mViewModel.setSelectedDateTimeMillis(bundle.getLong("todaysDateForMyTour", Calendar.getInstance().getTimeInMillis()));
mSelectedTabId = bundle.getInt(KEY_SELECTED_TAB, 0);
}
mMyTourJobsListPagerAdapter = new MyTourJobsListPagerAdapter(this, mViewModel.getTourIdForSelectedDate(), this);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mFragmentMyTourBinding = getViewDataBinding();
mFragmentMyTourBinding.vpMyTour.setOffscreenPageLimit(2);
mFragmentMyTourBinding.vpMyTour.setCurrentItem(0);
mFragmentMyTourBinding.vpMyTour.setAdapter(mMyTourJobsListPagerAdapter);
mFragmentMyTourBinding.tabLayoutMyTour.setupWithViewPager(mFragmentMyTourBinding.vpMyTour, true);
mFragmentMyTourBinding.tabLayoutMyTour.addOnTabSelectedListener(this);
setUpTabs();
}
private void setUpTabs() {
//Select the current Tab.
mFragmentMyTourBinding.vpMyTour.setCurrentItem(mSelectedTabId);
//Refresh job list as per the selected date.
FragmentMyTourJobsList fragmentMyTourJobsList = mMyTourJobsListPagerAdapter.getFragmentAtTab(mSelectedTabId); **// this is null first time**
if (fragmentMyTourJobsList != null) {
fragmentMyTourJobsList.refreshJobsList(mViewModel.getTourIdForSelectedDate());
}
}
}
Here is MyTourJobsListPagerAdapter code :
public class MyTourJobsListPagerAdapter extends FragmentStatePagerAdapter {
private static final int MY_TOUR_JOBS_LIST_PAGES_COUNT = 3;
private static final int POSITION_TAB_PENDING = 0;
private static final int POSITION_TAB_SUCCESS = 1;
private static final int POSITION_TAB_FAILED = 2;
private HashMap<Integer, FragmentMyTourJobsList> mTabsFragments = new HashMap<Integer, FragmentMyTourJobsList>();
private long mTourId;
private FragmentMyTourJobsList.FragmentMyTourJobsListListener mFragmentMyTourJobsListListener;
public MyTourJobsListPagerAdapter(Fragment fragment, long tourId, FragmentMyTourJobsList.FragmentMyTourJobsListListener fragmentMyTourJobsListListener) {
super(fragment.getChildFragmentManager(), BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.mTourId = tourId;
this.mFragmentMyTourJobsListListener = fragmentMyTourJobsListListener;
}
public void setTourId(long tourId) {
this.mTourId = tourId;
}
#Override
public int getCount() {
return MY_TOUR_JOBS_LIST_PAGES_COUNT;
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
mTabsFragments.put(position, (FragmentMyTourJobsList) fragment);
return fragment;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
mTabsFragments.remove(position);
super.destroyItem(container, position, object);
}
#Override
public Fragment getItem(int position) {
FragmentMyTourJobsList fragmentMyTourJobsList;
switch (position) {
case POSITION_TAB_SUCCESS:
fragmentMyTourJobsList = getFragmentWithBundle(Constants.JOB_STATUS_SUCCESSFUL);
break;
case POSITION_TAB_FAILED:
fragmentMyTourJobsList = getFragmentWithBundle(Constants.JOB_STATUS_FAILED);
break;
case POSITION_TAB_PENDING:
default:
fragmentMyTourJobsList = getFragmentWithBundle(Constants.JOB_STATUS_ACCEPTED);
break;
}
return fragmentMyTourJobsList;
}
public FragmentMyTourJobsList getFragmentAtTab(int tabPosition) {
return mTabsFragments.get(tabPosition);
}
private FragmentMyTourJobsList getFragmentWithBundle(String jobsStatus) {
FragmentMyTourJobsList fragmentToLoad = FragmentMyTourJobsList.newInstance();
Bundle bundle = new Bundle();
bundle.putString(FragmentMyTourJobsList.KEY_ARG_JOBS_STATUS, jobsStatus);
bundle.putLong(FragmentMyTourJobsList.KEY_ARG_TOUR_ID, mTourId);
bundle.putSerializable(FragmentMyTourJobsList.KEY_ARG_FRAGMENT_MY_TOUR_JOBS_LIST_LISTENER, mFragmentMyTourJobsListListener);
fragmentToLoad.setArguments(bundle);
return fragmentToLoad;
}
}
Everything is working but when i will go to Pending tab first time then it's not working. I am missing anything here?
Added FragmentMytourJobList
public class FragmentMyTourJobsList extends BaseFragment<FragmentMyTourJobsListBinding, MyTourJobsListViewModel> implements MyTourJobsListNavigator {
public static FragmentMyTourJobsList newInstance() {
return new FragmentMyTourJobsList();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewModel.setNavigator(this);
Bundle bundle = this.getArguments();
if (bundle != null) {
mJobsStatus = bundle.getString(KEY_ARG_JOBS_STATUS);
mTourId = bundle.getLong(KEY_ARG_TOUR_ID, 0);
}
}
#Override
public int getBindingVariable() {
return myTourJobsListViewModel;
}
#Override
public int getLayoutId() {
return R.layout.fragment_my_tour_jobs_list;
}
#Override
public MyTourJobsListViewModel getViewModel() {
mViewModel = ViewModelProviders.of(this, new ViewModelProviderFactory(Objects.requireNonNull(getActivity()).getApplication())).get(MyTourJobsListViewModel.class);
return mViewModel;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mFragmentMyTourJobsListBinding = getViewDataBinding();
// fetch job list from database
ArrayList<JobUiModel> jobList = mViewModel.fetchJobs(mTourId, mJobsStatus);
RecyclerView.LayoutManager rvLayoutManager = new LinearLayoutManager(getActivity());
mFragmentMyTourJobsListBinding.rvMyTourJobs.setLayoutManager(rvLayoutManager);
// initialize adapter
mJobsListAdapter = new MyTourJobsListAdapter(getContext(), jobList, mJobsStatus);
mFragmentMyTourJobsListBinding.rvMyTourJobs.setAdapter(mJobsListAdapter);
mJobsListAdapter.setClickInterface(this);
mFragmentMyTourJobsListBinding.rvMyTourJobs.addItemDecoration(new EndOffsetItemDecoration(CommonUtils.dpToPx(56)));
}
void refreshJobsList(long tourId) {
if (tourId > 0) {
mTourId = tourId;
mViewModel.fetchJobs(tourId, mJobsStatus);
// fetch job list from database
ArrayList<JobUiModel> jobList = mViewModel.fetchJobs(mTourId, mJobsStatus);
mJobsListAdapter.setDataset(jobList);
mJobsListAdapter.notifyDataSetChanged();
} else {
mJobsListAdapter.setDataset(null);
mJobsListAdapter.notifyDataSetChanged();
}
}
}
I'm a beginner who learning Android basic course
I want to make 6 fragments that have same structure (only title, image, texts will be different) by using single fragment.
I tried this code but I can see only one fragment.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.fragment_container);
MoviePagerAdapter adapter = new MoviePagerAdapter(getSupportFragmentManager());
mainfragment = new MainFragment();
adapter.addItem(mainfragment);
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(6);
}
ViewPager Adapter (in MainActivity)
class MoviePagerAdapter extends FragmentStatePagerAdapter {
public ArrayList<Fragment> items = new ArrayList<Fragment>();
#Override
public Fragment getItem(int position) {
return items.get(position);
}
public MoviePagerAdapter(#NonNull FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
public void addItem(Fragment item) {
items.add(item);
}
#Override
public int getCount() {
return items.size();
}
}
MainFragment.java
public class MainFragment extends androidx.fragment.app.Fragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.main_frargment, container,
false);
//...
'i want to make 6fragments with datas below '
movieData = new MovieData("title1", "rate1", "grade1");
addData(movieData);
movieData = new MovieData("title2", "rate2", "grade2");
addData(movieData);
movieData = new MovieData("title3", "rate3", "grade3");
addData(movieData);
movieData = new MovieData("title4", "rate4", "grade4");
addData(movieData);
movieData = new MovieData("title5", "rate5", "grade5");
addData(movieData);
movieData = new MovieData("title6", "rate6", "grade6");
addData(movieData);
return rootView;
}
public void addData(MovieData movieData){
Bundle bundle = new Bundle();
bundle.putParcelable("data", movieData);
MainFragment mainFragment = new MainFragment();
mainFragment.setArguments(bundle);
title.setText(movieData.title);
reservation_rate.setText(movieData.getReservation_rate());
grade.setText(movieData.getGrade());
image.setImageResource(R.drawable.image6);
}
}
change your code like this:
public class MainActivity extends AppCompatActivity {
private MoviePagerAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.fragment_container);
adapter = new MoviePagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(6);
for(int i =0;i<6;i++){
createFrag(i);
}
}
}
private void createFrag(int number) {
MainFragment fragment = new MainFragment();
Bundle args = new Bundle();
args.putInt("NUMBER",number);
fragment.setArguments(args);
adapter.addItem(fragment);
adapter.notifyDataSetChanged();
}
class MoviePagerAdapter extends FragmentStatePagerAdapter {
public ArrayList<Fragment> items = new ArrayList<Fragment>();
#Override
public Fragment getItem(int position) {
return items.get(position);
}
public MoviePagerAdapter(#NonNull FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
public void addItem(Fragment item) {
items.add(item);
}
#Override
public int getCount() {
return items.size();
}
}
and change your Fragment like this:
public class MainFragment extends androidx.fragment.app.Fragment {
//1st
private int number;
#Nullable
//this is variant 1 - with static Movie data
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable
ViewGroup container, #Nullable Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.main_frargment,
container,
false);
//...
//2d
assert getArguments() != null;
number = getArguments().getInt("NUMBER");
switch (number) {
case 0:
MmovieData movieData1 = new MovieData("title1", "rate1",
"grade1");
addData(movieData1);
break;
case 1:
MmovieData movieData2 = new MovieData("title2", "rate2",
"grade2");
addData(movieData2);
break;
//...
}
return rootView;
}
public void addData(MovieData movieData){
title.setText(movieData.title);
reservation_rate.setText(movieData.getReservation_rate());
grade.setText(movieData.getGrade());
image.setImageResource(R.drawable.image6);
}
}
and this is variant 2 ( with dynamic data and listener)
public class MainFragment extends androidx.fragment.app.Fragment {
//1st
private int number;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable
ViewGroup container, #Nullable Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.main_frargment,
container,
false);
//...
//2d
assert getArguments() != null;
number = getArguments().getInt("NUMBER");
return rootView;
}
//some method of listener changed
public void dataChanged(MovieData movieData, int position){
if(number==position){
title.setText(movieData.title);
reservation_rate.setText(movieData.getReservation_rate());
grade.setText(movieData.getGrade());
image.setImageResource(R.drawable.image6);
}
}
I have been facing this problem when rotation of the screen happens.I have seen all the similar posts of the stackoverflow but no luck.
Here is my activity with two fragments NEwsList and NewsDetails
NewsDetails fragment will get called when an item from the list is clicked.
public class MainActivity extends AppCompatActivity implements OnNewsItemClicked, PresenterLocator {
#Bind(R.id.news_list_fragment)
FrameLayout listFragmentContainer;
#Nullable
#Bind(R.id.news_details_fragment)
FrameLayout newsDetailsContainer;
private boolean isTablet;
private NewsScreenPresenter presenter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
isTablet = newsDetailsContainer == null ? false : true;
presenter = (NewsScreenPresenter) getLastCustomNonConfigurationInstance();
if (presenter == null) {
presenter = new NewsScreenPresenter(new NewsRetrofitGateway(), this);
}
if (savedInstanceState == null) {
attachListFragment();
}
}
private void attachListFragment() {
Fragment listFragment = new NewsListFragment();
Bundle bundle = new Bundle();
bundle.putBoolean(NewsListFragment.IS_TABLET, isTablet);
listFragment.setArguments(bundle);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.news_list_fragment, listFragment);
transaction.commit();
}
#Override
public Object onRetainCustomNonConfigurationInstance() {
return presenter;
}
#Override
public void onNewsItemClicked(String title, String summary, String picUrl, String storyUrl) {
if (!isFinishing()) {
Fragment fragment = new NewsDetailFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
fragment.setArguments(NewsDetailFragment.buildArguments(title, summary, picUrl, storyUrl));
if (!isTablet) {
transaction.add(R.id.news_list_fragment, fragment);
transaction.addToBackStack(null);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
} else {
transaction.replace(R.id.news_details_fragment, fragment);
}
transaction.commit();
}
}
#Override
public NewsScreenPresenter getPresenter() {
return presenter;
}}
NewsListFramgment
public class NewsListFragment extends Fragment implements NewsScreenView {
public static final String IS_TABLET = "is_tablet";
private NewsScreenPresenter presenter;
#Bind(R.id.progressBar)
LinearLayout progressBar;
#Bind(R.id.recycler_view)
RecyclerView recyclerView;
private boolean isTablet;
private PresenterLocator locator;
#Override
public void onAttach(Context context) {
super.onAttach(context);
locator = (PresenterLocator) context;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View listView = inflater.inflate(R.layout.new_list_layout, null);
ButterKnife.bind(this, listView);
return listView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
recyclerView.setHasFixedSize(true);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
isTablet = getArguments().getBoolean(IS_TABLET);
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
presenter = locator.getPresenter();
presenter.onViewCreated(this);
}
#Override
public void showProgressBar() {
progressBar.setVisibility(View.VISIBLE);
}
#Override
public void hideProgress() {
if (progressBar.getVisibility() == View.VISIBLE) {
progressBar.setVisibility(View.GONE);
}
}
#Override
public void populateNewsInList(final NewsResponseMapper news) {
NewsListAdapter adapter = new NewsListAdapter(news, new OnRecycleItemClick() {
#Override
public void onItemClick(int position) {
presenter.onItemClick(position);
}
});
recyclerView.setAdapter(adapter);
if (isTablet) {
presenter.onItemClick(0);
}
}
#Override
public void showError(String errorMsg) {
Toast.makeText(getActivity(), errorMsg, Toast.LENGTH_LONG).show();
}
interface OnRecycleItemClick {
void onItemClick(int position);
}
NewsDetialsFragment
public class NewsDetailFragment extends Fragment {
public static final String STORY_URL = "storyURL";
public static final String TITLE = "title";
public static final String SUMMARY = "summary";
public static final String IMAGE_URL = "imageURL";
private BrowserNavigation browserNavigation;
#Bind(R.id.title)
TextView titleView;
#Bind(R.id.summary_content)
TextView summaryView;
#Bind(R.id.news_image)
DraweeView imageView;
public static Bundle buildArguments(String title, String summary,
String picUrl, String storyUrl) {
Bundle bundle = new Bundle();
bundle.putString(TITLE, title);
bundle.putString(SUMMARY, summary);
bundle.putString(IMAGE_URL, picUrl);
bundle.putString(STORY_URL, storyUrl);
return bundle;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View detailsView = inflater.inflate(R.layout.activity_detail, null);
ButterKnife.bind(this, detailsView);
return detailsView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bundle extras = getArguments();
String storyURL = extras.getString(STORY_URL);
String title = extras.getString(TITLE);
String summary = extras.getString(SUMMARY);
String imageURL = extras.getString(IMAGE_URL);
browserNavigation = new BrowserNavigation(getActivity(), storyURL);
titleView.setText(title);
summaryView.setText(summary);
DraweeController draweeController = Fresco.newDraweeControllerBuilder()
.setImageRequest(ImageRequest.fromUri(Uri.parse(imageURL)))
.setOldController(imageView.getController()).build();
imageView.setController(draweeController);
}
#OnClick(R.id.full_story_link)
public void fullStoryClicked() {
browserNavigation.navigate();
}
By Looking at the code you can understand that i am following MVP architecture and while i see the NewsListFragment and rotate the device i am saving my presenter in the activity using onRetianCustomNonConfiguration() callback, so as not to call the server again to fetch the list of news again.
Everything works fine as expected but after the rotation whenever i try to click an item in the list to show the DetailsFragment(onNewsItemClick()) it crashes with illegalStateException "can't perform this action after OnSavedInstanceState".
Can anyone point out the mistake i am doing here?
FATAL EXCEPTION: main
Process: news.agoda.com.technewssample, PID: 24160
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1493)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1511)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:638)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:617)
at news.agoda.com.sample.presentation.MainActivity.onNewsItemClicked(MainActivity.java:96)
at news.agoda.com.sample.NewsScreenPresenter.onItemClick(NewsScreenPresenter.java:55)
at news.agoda.com.sample.presentation.NewsListFragment$1.onItemClick(NewsListFragment.java:89)
at news.agoda.com.sample.presentation.NewsListAdapter$1.onClick(NewsListAdapter.java:76)
at android.view.View.performClick(View.java:4785)
at android.view.View$PerformClick.run(View.java:19888)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5276)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:911)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:706)
This is my PagerAdapter.
public class SlideAdapter extends PagerAdapter{
private List<ImageView> views;
public SlideAdapter (List<ImageView> views){
this.views=views;
}
#Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView(views.get(position));
}
#Override
public int getCount() {
return views.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
#Override
public Object instantiateItem(View container, int position) {
((ViewPager) container).addView(views.get(position));
return views.get(position);
}
}
This is my fragment.
public class sportfragment extends Fragment {
private ViewPager slideviewpager;
private Boolean isContinue=true;
private AtomicInteger what=new AtomicInteger (0);
private ImageView[] indiimageview;
private List<ImageView> pics;
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public sportfragment() {
}
public static sportfragment newInstance(String param1, String param2) {
sportfragment fragment = new sportfragment();
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);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_sportfragment, container, false);
slideviewpager=(ViewPager) view.findViewById(R.id.slideviewpager);
ViewGroup indicatorgroup=(ViewGroup) view.findViewById(R.id.indicatorgroup);
pics=new ArrayList<ImageView>();
ImageView slide1=new ImageView(view.getContext());
slide1.setBackgroundResource(R.drawable.slide1);
pics.add(slide1);
ImageView slide2=new ImageView(view.getContext());
slide1.setBackgroundResource(R.drawable.slide2);
pics.add(slide2);
ImageView slide3=new ImageView(view.getContext());
slide1.setBackgroundResource(R.drawable.slide3);
pics.add(slide3);
ImageView slide4=new ImageView(view.getContext());
slide1.setBackgroundResource(R.drawable.slide4);
pics.add(slide4);
indiimageview=new ImageView[pics.size()];
for (int i=0;i<pics.size();i++) {
ImageView buff=new ImageView(view.getContext());
buff.setLayoutParams(new LinearLayout.LayoutParams(20,20));
buff.setPadding(5,5,5,5);
indiimageview[i]=buff;
if (i==0) {
indiimageview[i].setBackgroundResource(R.drawable.focus);
}else {
indiimageview[i].setBackgroundResource(R.drawable.blur);
}
indicatorgroup.addView(indiimageview[i]);
}
slideviewpager.setAdapter(new SlideAdapter(pics));
slideviewpager.setOnPageChangeListener(new GuidePageChangeListener());
return view;
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
private final class GuidePageChangeListener implements ViewPager.OnPageChangeListener{
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
for (int i=0;i<indiimageview.length;i++) {
if (i==position) {
//4 points change with viewpager
indiimageview[i].setBackgroundResource(R.drawable.focus);
} else {
indiimageview[i].setBackgroundResource(R.drawable.blur);
}
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
}
First page is the Image.
But other 3 is blank.
Is there any way to solve this?
ViewPagers are meant to be used with fragments, not views. This means that you should be packaging your ImageViews as Fragments rather than plain old views.
Consider the following example:
MyImageView.java
public class MyImageFragment extends Fragment {
private ImageView mImageView;
private int resourceId;
public static MyImageFragment newInstance(int resourceId) {
MyImageFragment fragment = new MyImageFragment();
Bundle args = new Bundle();
args.putInt("resource_id", resourceId);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Bundle args = getArguments();
if (args != null && !loadedFromArgs) {
url = (String)args.getSerializable("url");
resourceId = args.getInt("in_list", -1);
loadedFromArgs = true;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.fragment_my_image, container, false);
mImageView = (ImageView) rootView.findViewById(R.id.image);
mImageView.setBackgroundDrawable(getResources().getDrawable(resourceId))
return rootView;
}
}
fragment_my_image.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
</RelativeLayout>
Now, instead of a list of ImageViews, you will have a list of MyImageFragments that your PagerAdapter will point to.