Android, Functions in Adapter never get called - android

Functions like onCreateViewHolder(), onBindViewHolder(), onAttachedToRecyclerView() never get called. This is what I'm trying to do.
Switch from MainActivity to RecyclerViewActivity when Button1 is clicked, and load fragment_recyclerview into RecyclerViewActivity
switch(id) {
case R.id.aboutMeButton:
getSupportFragmentManager().beginTransaction().replace(R.id.mainContainer, AboutMeFragment.newInstance()).addToBackStack(null).commit();
break;
case R.id.task1Button:
intent = new Intent(this, RecyclerViewActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT );
startActivity(intent);
break;
default:
break;
}
FragmentViewActivity.onCreate()
FragmentViewActivity.onCreate()
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recyclerview);
getSupportFragmentManager().beginTransaction().replace(R.id.recyclerViewContainer, RecyclerViewFragment.newInstance()).commit();
Log.d("AAA", "RecyclerViewActivity.onCreate( )");
}
RecyclerViewFragment.onCreateView():
RecyclerViewFragment.onCreateView(){
final View rootView = inflater.inflate(R.layout.fragment_recyclerview, container, false);
movieData = new MovieData();
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.cardViewContainer);
// Log.d("AAA", "mRecyclerView = " + mRecyclerView.getId());
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
Log.d("AAA", "getActivity() = " + getActivity().toString());
Log.d("AAA", "movieList size = " + movieData.getMoviesList().size());
// specify an adapter (see also next example)
mAdapter = new MovieDataAdapter(getActivity(), movieData.getMoviesList());
mRecyclerView.setAdapter(mAdapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
Adapter.getItemCount() returns 30, however, functions in adapter other than constructor never get called, which leaves me a pure blank
screen. I've no idea what's going on

You are setting your View up in rootView and then, instead of returning that View, you return super.onCreateView():
Instead of the following in onCreateView():
return super.onCreateView(inflater, container, savedInstanceState);
You should return the View you just set up:
return rootView;

first:
don't do any initialization of adapter in Fragment.onCreateView(,,,)
as name says this method should be used to inflate or create view:
so inflate view:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.recycler_layout, container, false);
}
after u create view use onViewCreated(..) method to initialize and create adapter:
#Override
public void onViewCreated(View view, Bundle savedInstanceState){
// here initialize recycler view
super.onViewCreated(view, savedInstanceState);
}
and as user13 said you need to return inflated view not super created view !!!!*
then u will avoid such problems
second:
depending on fragment/parent component usage (for example you should use different approach when u implement view pager with state or normal adapter, or you retain fragment) sometimes you can or sometimes can't hold reference to inflated view (thus return or not once created view) - but as i sad it's depends what approach do you use

Related

Empty View in Fragment

I have a question. Currently, I am creating a small Android app with Android Studio. I have two fragments. In fragment 1 I have an overview of tiles. These are passed to the RecyclerView via an adapter. This is all handled in onCreateView.
When clicking on a card, I get to fragment 2 using navigation (NavHostFragment.findNavController(CategoryFragment.this) .navigate(R.id.action_Category_to_Second);) This works.
When I click the back button from fragment 2 (toolbar) to fragment 1, the view remains empty. Why? Or does anyone know a code example where I can rebuild this?
Am I doing something wrong here by overdriving the view?
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_category, container, false);
categoriesData = new CategoriesService( view.getContext(), this.queue, this.sharedPreferences);
categoriesData.loadData();
CardViewAdapter mAdapter = new CardViewAdapter(view.getContext(), categoriesData.getCategories());
mAdapter.setClickListener(this);
recyclerView = view.findViewById(R.id.categoriesGrid);
recyclerView.setLayoutManager(new GridLayoutManager(view.getContext(), 6));
recyclerView.setAdapter(mAdapter);
view zurückgeben;
}

Where should I put logic in the Java tab layouts

I have 2 fragments each fragments has a different java logic. Where should i put the java logic? if i did put it in the fragments,then error message displays :
cannot resolve method findViewById, Cannont resolve method getApplicationContext
it appear that you did not inflate the view correctly, change your code to be something like this :
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.your_fragment, container, false);
mButton = (Button) view.findViewById(R.id.mButton );
list_content = (ListView) view.findViewById(R.id.list_content);
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(dataAdapter);
return view;
}
and you should use 'getActivity()' method for context not 'This' .
You can find other view's Id's in your fragment like this.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.your_layout,container,false);
tabLayout = (TabLayout)view.findViewById(R.id.tabs);
return view;
}
When you inflate the view on the oncreateview make a view field like this :
View view = inflater.inflate(R.layout..., container, false);
and return with this view.
After that with this variable you can reach the findViewById, like
view.findViewById
Instead of getApplicationContext you can use getContext in fragment.
Good luck.

Slow fragment creation

I have a view pager with multiple fragments but, I'm facing some performance problems as the onCreateView of the fragment is really slow. I've seen that the fragment takes some time to create the view, why is this?
In order to solve that I've thought about using a private variable so the view mustn't be recreated each time. The code would be as bellow (as you can see in the code, the content of the fragment is just a recyclerview):
private View iView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(iView != null) {
return iView;
}
iView = inflater.inflate(R.layout.fr_view, container, false);
rv = (RecyclerView) iView.findViewById(R.id.rv);
rv.setHasFixedSize(true);
final GridLayoutManager iLayoutManager = new GridLayoutManager(getActivity(), MAX_COLUMNS);
rv.setLayoutManager(iLayoutManager);
rv.setAdapter(iAdapter);
rv.setItemAnimator(new DefaultItemAnimator());
return iView;
}
Is that a good solution? Why inflating the view may be taking so time?
Thanks in advance!

getting force close when using findviewbyId()

I'm starting to learn android app development and currently practicing with simple apps. I'm writing this app that includes a listview and i want to fill it with fake data but, when i use findViewbyId() in my code the app gives me force close BUT when i set the content view to my fragment instead of activity_main i get no force close, but the app shows me an empty list.
This is my code :
package com.example.karen.please;
public class MainActivityFragment extends Fragment {
private ArrayAdapter<String> mForecastAdapter;
public MainActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String[] forecastArray =
{
"sunny",
"cloudy",
"asteroids",
"rainy",
"sunny"
};
List<String> weekforecast = new ArrayList<String>(Arrays.asList(forecastArray));
mForecastAdapter =
new ArrayAdapter<String>(
getActivity(),
R.layout.list_item_forecast,
R.id.list_item_forecast_textview,
weekforecast
);
ListView mylistview = (ListView)container.findViewById(R.id.listview_forecast); //screws upp in this line
mylistview.setAdapter(mForecastAdapter);
return inflater.inflate(R.layout.fragment_main, container, true);
}}
Any help would be appreciated.
You're trying to find a view before you inflate your layout... Try inflating at the top of your method, like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myView = inflater.inflate(R.layout.fragment_main, container, true);
<all the other init code you have>
return myView;
}
First you need inflate your layout...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
...
ListView mylistview = (ListView)rootView.findViewById(R.id.listview_forecast);
...
Before using findViewById you should Create a View variable, use the inflate.. line, use findViewById on the View variable you created, and then return that.
This is what your code should look like:
package com.example.karen.please;
public class MainActivityFragment extends Fragment {
private ArrayAdapter<String> mForecastAdapter;
public MainActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Instead of inflate and return instantly, store it in a variable,
// Then return at the end of the method.
View view = inflater.inflate(R.layout.fragment_main, container, true);
[...]
// Here, use findViewById on the View you have just inflated.
ListView mylistview = (ListView) view.findViewById(R.id.listview_forecast); //screws upp in this line
mylistview.setAdapter(mForecastAdapter);
// Return the view you created on the beginning.
return view;
}}
You should start with a proper tutorial not chaotically adding code that you don't understand. Start reading here:
Creating and Using Fragments
After you understood how it goes then you will see that first you need to inflate the layout that contains the stuff you want to find by id and then by using the view(that defines the layout) you can find the desired view(listview, etc).
ListView my listview = (ListView).findViewById(R.id.listview_forcast);
I think this is how it should be, no container in the code

RecyclerView saving state

Anyone have issue that RecyclerView doesn't save scroll position after changing orientation?
mMyAdapter = new MyAdapter(context, MyAdapter.generateKey(this), savedInstanceState);
mMyAdapter.setHasStableIds(true);
mLayoutManager = new LinearLayoutManager(context, VERTICAL, false);
int padding = ResourceUtils.dp2px(context, 8);
mRecycleView.setClipToPadding(false);
mRecycleView.setPadding(0, ResourceUtils.getPixelSize(R.dimen.toolbar_height), 0, padding);
mRecycleView.setOverScrollMode(View.OVER_SCROLL_ALWAYS);
mRecycleView.setLayoutManager(mLayoutManager);
mRecycleView.setAdapter(MyAdapter);
mRecycleView.setHasFixedSize(false);
mRecycleView.setOnScrollListener(mScrollManager); // only to hide Toolbar on scroll
so i'm not modifed onDestroy or OnSaveInstanceState methods, only saving adapters data, so when i'm rotating phone, scroll position of RecyclerView reseting, some advice?
Recently I've improved and created a FlexibleAdapter pattern for all RecyclerView. It is able to maintain the state after rotation.
Very simple to use, just copy 2 classes in your common files + some xml in order to enable the selection (Single/Multi) as it was for ListView.
Please have a look at the description and full working example: https://github.com/davideas/FlexibleAdapter
I understood where i had mistake, i used RecyclerView from
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
//used this instance of recycler view
mRecyclerView = inflater.inflate(R.layout.recycle_fragment, container, false);
return mRecyclerView;
}
but need to
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// instead of searching it after view created
mRecycleView = ButterKnife.findById(getView(), R.id.recycler_view);
}
Problem solved

Categories

Resources