I've searched and searched for this question and tried many different solutions but nothing seems to be working.
I'm trying to access an object in my fragment layout but its turning up null and I realize that my OnFragmentInteractionListener is null which is leading me to believe it's not attracting the right fragment.
This is pretty much a copy paste from another activity of the app and that activity works perfectly fine. For some reason, this one just does not want to communicate.
TLDR: mListener in my Fragment (negativeThoughtView.java) is null
I only included the important parts of the code to shorten it:
Activity (JournalView.java)
public class JournalView extends AppCompatActivity implements negativeThoughtView.OnFragmentInteractionListener, distortionView.OnFragmentInteractionListener, challengingThoughtView.OnFragmentInteractionListener {
TabLayout thoughtsTab;
ViewPager viewPager;
PagerAdapterView adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_journal_view);
thoughtsTab = (TabLayout) findViewById(R.id.thoughtsViewTabs);
thoughtsTab.addTab(thoughtsTab.newTab().setText("Negative Thoughts"));
thoughtsTab.addTab(thoughtsTab.newTab().setText("Distortions"));
thoughtsTab.addTab(thoughtsTab.newTab().setText("Challenging Thoughts"));
thoughtsTab.setTabGravity(thoughtsTab.GRAVITY_FILL);
adapter = new PagerAdapterView(getSupportFragmentManager(), thoughtsTab.getTabCount());
viewPager = (ViewPager) findViewById(R.id.thoughtsViewPager);
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(thoughtsTab));
thoughtsTab.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
negativeThoughtView NegativeThoughtView =(negativeThoughtView) adapter.instantiateItem(viewPager, 0);
distortionView DistortionView =(distortionView) adapter.instantiateItem(viewPager, 1);
challengingThoughtView ChallengingThoughtView =(challengingThoughtView) adapter.instantiateItem(viewPager, 2);
if (NegativeThoughtView != null) {
String negativeThoughts = "Tester";
NegativeThoughtView.onButtonPressed(negativeThoughts);
}
if (ChallengingThoughtView != null) {
String challengingThoughts= "Tester";
ChallengingThoughtView.onButtonPressed(challengingThoughts);
}
if (DistortionView != null) {
String distortions= "Tester";
DistortionView.onButtonPressed(distortions);
}
}
#Override
public void onFragmentInteraction(Uri uri) {
}
#Override
public void negativeThoughtView(String string) {
}
#Override
public void challengingThoughtView(String string) {
}
#Override
public void distortionView(String string) {
}
}
Fragment (negativeThoughtsView.java)
public class negativeThoughtView extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
TextView negativeThoughtEntry;
private OnFragmentInteractionListener mListener;
public negativeThoughtView() {
// Required empty public constructor
}
public static negativeThoughtView newInstance(String param1, String param2) {
negativeThoughtView fragment = new negativeThoughtView();
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.fragment_negative_thought_view, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
negativeThoughtEntry = (TextView) getView().findViewById(R.id.negativeThoughtEntry3);
}
public void onButtonPressed(String negativeThought) {
Log.d("Passer","1");
if (mListener != null) {
Log.d("Passer","2");
negativeThoughtEntry.setText(negativeThought);
//mListener.negativeThoughtView(negativeThought);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
Log.d("Passer","mListener good");
} else {
Log.d("Passer","mListener null");
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
void negativeThoughtView(String string);
}
}
Related
I am giving product id with barcode scanner. I can add product to listView but when i try to increase or decrease amount of the product. It doesn't update UI. I used Toast message to see weather list is updated, it updates list but doesn't update UI
I have tried to use runOnUiThread() but i couldn't find any solution. How to update UI can you please help me
custom_lisView_row
BaseActivity which keeps MainFragment on it
public class BaseActivity extends AppCompatActivity {
public static final String MAIN_FRAGMENT = "mainFragment";
public static final String PRODUCTS = "products";
FragmentManager fragmentManager;
Dialog dialog ;
public static ArrayList<MyProduct> myProductList = new ArrayList<>();
public static MyTablet myTablet = new MyTablet();
Activity mActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
//Initialize fragment manager
fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.fl_BaseActivity, new MainFragment()).commit();
//Create database
mDatabase = FirebaseDatabase.getInstance().getReference();
dialog = new Dialog(this);
//Runs when i enter product id
initScanner();
}
public void updateMyProductList(MyProduct myProduct){
for(int i= 0 ; i< myProductList.size() ; i++ ){
MyProduct temp = myProductList.get(i);
if (temp.getId().equals(myProduct.getId())) {
temp.setAmount(temp.getAmount() + myProduct.getAmount());
myProductList.set(i, temp);
return;
}
}
myProductList.add(myProduct);
updateMainFragment();
}
private void initScanner() {
mDatabase.child(PRODUCTS).child(finalData).get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
MyProduct myProduct = task.getResult().getValue(MyProduct.class);
myProduct.setAmount(1);
dialog.setContentView(R.layout.custom_product_dialog);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.setCancelable(false);
TextView tv_addBasket_product_dialog = dialog.findViewById(R.id.tv_addBasket_product_dialog);
tv_addBasket_product_dialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
updateMyProductList(myProduct);
dialog.dismiss();
}
});
dialog.show();
}
};
}
public void updateMainFragment() {
if (isExist(MAIN_FRAGMENT)) {
Fragment fragment = findFragment(MAIN_FRAGMENT);
((MainFragment) fragment).updateMyList();
}
}
//Add fragments to BaseActivity
public void addFragments(Fragment fragment, String tag) {
fragmentManager.beginTransaction().add(R.id.fl_BaseActivity, fragment, tag).commit();
}
//Replace fragments to BaseActivity
public void replaceFragments(Fragment fragment, String tag) {
fragmentManager.beginTransaction().replace(R.id.fl_BaseActivity, fragment, tag).commit();
}
//Remove fragment from BaseActivity
public void removeFragment(String tag) {
Fragment fragmentB = fragmentManager.findFragmentByTag(tag);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (fragmentB != null) {
fragmentTransaction.remove(fragmentB);
fragmentTransaction.commit();
}
}
// finds fragment and returns it
// It may return null first check fragment is exist. use isExist() method
public Fragment findFragment(String tag) {
Fragment fragment = fragmentManager.findFragmentByTag(tag);
return fragment;
}
//Check fragment exist in BaseActivity
public boolean isExist(String tag) {
Fragment fragmentB = fragmentManager.findFragmentByTag(tag);
if (fragmentB != null) {
return true;
}
return false;
}
}
MainFragment
public class MainFragment extends Fragment {
ListView lv_MainFragment;
public MyProductListAdapter myListAdapter;
public static ArrayList<MyProduct> myProductList;
Activity mActivity;
#Override
public void onAttach(Context context) {
super.onAttach(context);
mActivity = getActivity();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myProductList = BaseActivity.myProductList;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
lv_MainFragment = view.findViewById(R.id.lv_MainFragment);
myListAdapter = new MyProductListAdapter(mActivity.getApplicationContext(), R.layout.custom_product_list_row, myProductList);
lv_MainFragment.setAdapter(myListAdapter);
return view;
}
public void updateMyList() {
myProductList = BaseActivity.myProductList;
myListAdapter.notifyDataSetChanged();
}
}
MyProductListAdapter
public class MyProductListAdapter extends ArrayAdapter<MyProduct> {
private Context mContext;
private ArrayList<MyProduct> list;
AppCompatButton acb_DecreaseAmount_productListRow, acb_IncreaseAmount_productListRow;
public MyProductListAdapter(Context context, int resource, ArrayList<MyProduct> objects) {
super(context, resource, objects);
this.mContext = context;
this.list = objects;
}
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.custom_product_list_row, parent, false);
tv_ProductAmount_productListRow = view.findViewById(R.id.tv_ProductAmount_productListRow);
acb_DecreaseAmount_productListRow = view.findViewById(R.id.acb_DecreaseAmount_productListRow);
acb_IncreaseAmount_productListRow = view.findViewById(R.id.acb_IncreaseAmount_productListRow);
tv_ProductAmount_productListRow.setText(String.valueOf(list.get(position).getAmount()));
acb_IncreaseAmount_productListRow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
double productPrice = list.get(position).getPrice();
int productAmount = list.get(position).getAmount();
productAmount++;
list.get(position).setAmount(productAmount);
Toast.makeText(mContext, String.valueOf(productAmount), Toast.LENGTH_SHORT).show();
tv_ProductAmount_productListRow.setText(String.valueOf(list.get(position).getAmount()));
}
});
acb_DecreaseAmount_productListRow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int productAmount = list.get(position).getAmount();
if (productAmount > 1) {
double productPrice = list.get(position).getPrice();
productAmount--;
list.get(position).setAmount(productAmount);
Toast.makeText(mContext, String.valueOf(productAmount), Toast.LENGTH_SHORT).show();
tv_ProductAmount_productListRow.setText(String.valueOf(list.get(position).getAmount()));
}
}
});
}
return view;
}
}
Hej Metehan,
your use case sounds perfect for a RecyclerView with a ListAdapter. You just submit a new list of products to the adapter and it will handle the updating and notifying for you.
I am working on an android project with three tabs (3 tabs are created using Fragment class).
I created one Async inner class in Mainactivity and calling that class from onCreate(), but nothing is happening in the Logcat. Can anyone suggest me Where to define Async class which is getting resource in JSON format. Any better way of doing this thing is also welcome.
package com.utb.iftekhar.cityweatherappsnapshot1;
public class Tab2Fragment extends Fragment {
private static final String TAG="Tab2Fragment";
private Button button;
private static final String CITY_NAME_SEARCHED="cityNameSearched";
private List<String> historyList;
private ListView historyListView;
private ArrayAdapter<String> arrayAdapter;
String cityNameSearched="";
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.tab2_frag, container, false);
historyListView=view.findViewById(R.id.historyList);
historyList=new ArrayList<>();
if(getArguments()!=null){
cityNameSearched=getArguments().getString(CITY_NAME_SEARCHED);//Not able to set values to the ctiNameSearched variable.
}else
{
Log.i("No","Arguments");//
}
if(!(cityNameSearched==null) || !cityNameSearched.equals("")){
historyList.add(cityNameSearched);
Log.i("before", cityNameSearched);
Log.i("Value in tab2frag",cityNameSearched);
}
return view;
}
//This method is returning the searched city name searched int the edit text from fragment(Tab1Fragment) but not able to access this value in cityNameSearched variable.
public void updateEditText(String newText){
Log.i("received from 1 in 2",newText);
this.cityNameSearched=newText;
}
/*
#Override
public void onAttach(Context context) {
super.onAttach(context);
if(context instanceof Tab2FragmentListener){
tab2FragmentListener=(Tab2FragmentListener)context;
}else{
throw new RuntimeException(context.toString()+
" must implement Tab2FragmentListener"
);
}
}
#Override
public void onDetach() {
super.onDetach();
tab2FragmentListener=null;
}*/
}
public class Tab1Fragment extends Fragment{
private String weatherResults;
private Tab1FragmentListener tab1FragmentListener;
private String cityNameSearched;
public interface Tab1FragmentListener{
void onInput1Set(String input);
}
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.tab1_frag, container, false);
getWeatherButton=(Button)view.findViewById(R.id.getWeatherButton);
searchCityByName=(EditText)view.findViewById(R.id.searchCityByName);
weatherResultTextView=(TextView)view.findViewById(R.id.weatherResult);
mainActivity=new MainActivity();
getWeatherButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
downloadTask=new DownloadTask(new DownloadTask.AsyncResponse() {
#Override
public void processFinish(String output) {
if(!output.equals("")){
weatherResultTextView.setText(output);
}else{
weatherResultTextView.setText("");
}
}
});
cityNameSearched=searchCityByName.getText().toString().trim();
tab1FragmentListener.onInput1Set(cityNameSearched);
Log.i("CityNameSearched", cityNameSearched);
try {
String encodedCityName= URLEncoder.encode(cityNameSearched,"UTF-8" );
} catch (Exception e) {
e.printStackTrace();
}
downloadTask.execute("https://openweathermap.org/data/2.5/weather?q="+cityNameSearched+"&appid=b6907d289e10d714a6e88b30761fae22");
Log.i("Button Cliked","Clicked");
InputMethodManager mgr=(InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(searchCityByName.getWindowToken(), 0);
}
});
return view;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if(context instanceof Tab1FragmentListener){
tab1FragmentListener=(Tab1FragmentListener)context;
}else{
throw new RuntimeException(context.toString()+
" must implement Tab1FragmentListener"
);
}
}
#Override
public void onDetach() {
super.onDetach();
tab1FragmentListener=null;
}
public void updateEditText(String newText){
searchCityByName.setText(newText);
}
}
public class MainActivity extends AppCompatActivity implements Tab1Fragment.Tab1FragmentListener {
private static final String TAG="MainActivity";
private SectionsPageAdapter mySectionPageAdapter;
private ViewPager viewPager;
private DataForTabs dataForTabs;
private Tab1Fragment tab1Fragment;
private Tab2Fragment tab2Fragment;
String input="";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG,"onCreate: Starting.");
tab1Fragment=new Tab1Fragment();
Log.i(" From 1 to main ", input);//No Log appears for this input variable
mySectionPageAdapter=new SectionsPageAdapter(getSupportFragmentManager());
//set up the ViewPager with the sections adaptor
viewPager=(ViewPager)findViewById(R.id.container);
setupViewPager(viewPager);
TabLayout tabLayout=(TabLayout)findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
public void setupViewPager(ViewPager viewPager){
SectionsPageAdapter adapter=new
SectionsPageAdapter(getSupportFragmentManager());
adapter.addFragment(new Tab1Fragment(),"Home");
adapter.addFragment(new Tab2Fragment(),"History");
adapter.addFragment(new Tab3Fragment(),"About");
viewPager.setAdapter(adapter);
}
#Override
public void onInput1Set(String input) {
tab2Fragment.updateEditText(input);
this.input=input;
}
}
I'm a beginner on Android development and I was trying to make a simple app that has a recycleView inside a fragment using cardViews and when you click the like button inside of any of the items inside the list, the app then should send this item to another fragment called FavoriteFragment (which also contains recycleView) and display it here.
I tried to use an interface to do this, but whenever I click one of the like buttons, my activity does not receive the information (I tried to Log.d a message inside the method and is not being displayed)
here is the code for each of this:
My interface, what I am trying to use to pass the data from countries fragment-> adapter -> viewholder -> activity -> favorite fragment
public interface InterfaceListItemClickListener {
void listItemClickAction(ArrayList properties);
}
my CountriesFragment, which is the fragment that holds the first RecycleView:
public class CountriesFragment 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";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
ArrayList<RecycleViewItem> listCountries = new ArrayList<>();
String names[] = {"Thailand", "Venezuela", "Sweden"};
int images[] = {R.drawable.thailand, R.drawable.venezuela, R.drawable.sweden};
RecyclerView myRecyclerView;
InterfaceListItemClickListener sender;
public CountriesFragment() {
// Required empty public constructor
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
sender = (InterfaceListItemClickListener) getActivity();
}
public static CountriesFragment newInstance(String param1, String param2) {
CountriesFragment fragment = new CountriesFragment();
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);
}
initializeList();
}
public void initializeList(){
listCountries.clear();
for(int i = 0; i < names.length; i++){
RecycleViewItem item = new RecycleViewItem();
item.setCardName(names[i]);
item.setImageResourceID(images[i]);
item.setIsFav(0);
item.setIsTurned(0);
listCountries.add(item);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_countries, container, false);
myRecyclerView = (RecyclerView) view.findViewById(R.id.recycleView);
myRecyclerView.setHasFixedSize(true);
LinearLayoutManager myLayoutManager = new LinearLayoutManager(getActivity());
myLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
ListsForFragments.populateCountriesList();
if (ListsForFragments.countriesList.size() > 0 & myRecyclerView != null) {
myRecyclerView.setAdapter(new MyAdapter(ListsForFragments.countriesList, sender));
}
myRecyclerView.setLayoutManager(myLayoutManager);
return view;
}
// 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;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
}
My Adapter class:
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder>{
private ArrayList<RecycleViewItem> list = new ArrayList<RecycleViewItem>();
InterfaceListItemClickListener sender = null;
public MyAdapter(ArrayList<RecycleViewItem> list, InterfaceListItemClickListener sender) {
this.list = list;
this.sender = sender;
}
public MyAdapter(ArrayList<RecycleViewItem> list) {
this.list = list;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_items, parent, false);
MyViewHolder holder = new MyViewHolder(view, sender);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.titleTextView.setText(list.get(position).getCardName());
holder.coverImageView.setImageResource(list.get(position).getImageResourceID());
holder.coverImageView.setTag(list.get(position).getImageResourceID());
}
#Override
public int getItemCount() {
return list.size();
}
}
My viewHolder class:
public class MyViewHolder extends RecyclerView.ViewHolder{
public TextView titleTextView;
public ImageView coverImageView;
public ImageView likeImageView;
public ImageView shareImageView;
public ImageView favoriteImageView;
public TextView favoriteTextView;
private ArrayList goesToFavourites = new ArrayList();
public MyViewHolder(View itemView, final InterfaceListItemClickListener sender) {
super(itemView);
titleTextView = (TextView) itemView.findViewById(R.id.titleTextView);
coverImageView = (ImageView) itemView.findViewById(R.id.coverImageView);
likeImageView = (ImageView) itemView.findViewById(R.id.likeImageView);
shareImageView = (ImageView) itemView.findViewById(R.id.shareImageView);
favoriteImageView = (ImageView) itemView.findViewById(R.id.imageView_favorite);
favoriteTextView = (TextView) itemView.findViewById(R.id.textView_name_favorite);
if (likeImageView != null) {
likeImageView.setTag(R.drawable.ic_like);
likeImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int id = (int) likeImageView.getTag();
if (id == R.drawable.ic_like) {
likeImageView.setTag(R.drawable.ic_liked);
likeImageView.setImageResource(R.drawable.ic_liked);
if(sender != null) {
getGoesToFavourites().add(coverImageView);
getGoesToFavourites().add(likeImageView);
sender.listItemClickAction(getGoesToFavourites());
}
} else {
likeImageView.setTag(R.drawable.ic_like);
likeImageView.setImageResource(R.drawable.ic_like);
}
}
});
}
}
public ArrayList getGoesToFavourites() {
return goesToFavourites;
}
public void setGoesToFavourites(ArrayList goesToFavourites) {
this.goesToFavourites = goesToFavourites;
}
}
My favoriteFragment class, the one receiving the information:
public class FavoriteFragment extends Fragment {
private OnFragmentInteractionListener mListener;
RecyclerView myRecyclerView;
ArrayList receiver = new ArrayList();
public FavoriteFragment() {
}
public void receiveData(ArrayList receiver){
this.receiver = receiver;
}
public static FavoriteFragment newInstance() {
FavoriteFragment fragment = new FavoriteFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_favorite, container, false);
myRecyclerView = (RecyclerView) view.findViewById(R.id.recycleView);
myRecyclerView.setHasFixedSize(true);
LinearLayoutManager myLayoutManager = new LinearLayoutManager(getActivity());
myLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
if (receiver != null & myRecyclerView != null) {
myRecyclerView.setAdapter(new MyAdapter(receiver));
}
myRecyclerView.setLayoutManager(myLayoutManager);
return view; }
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;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
}
finally, my MainActivity, the bridge:
public class MainActivity extends AppCompatActivity implements
HostFragment.OnFragmentInteractionListener,
CountriesFragment.OnFragmentInteractionListener,
CitiesFragment.OnFragmentInteractionListener,
PlacesFragment.OnFragmentInteractionListener,
FavoriteFragment.OnFragmentInteractionListener,
ViewPagerFragment.OnFragmentInteractionListener,
InterfaceListItemClickListener{
FragmentManager fm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fm = getSupportFragmentManager();
//if this is the first time we are running the app
if(savedInstanceState == null){
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.content, new ViewPagerFragment());
transaction.commit();
}
}
#Override
public void onFragmentInteraction(Uri uri) {
}
#Override
public void listItemClickAction(ArrayList list) {
FavoriteFragment favorite = (FavoriteFragment)
fm.findFragmentById(R.id.favorite);
favorite.receiveData(list);
Log.d("INTERFACE", "Data received!" + list);
}
}
If any extra information needed let me know and I'll provide.
EDIT: so trying to debug, I found out that the InterfaceListItemClickListener that MyViewHolder is a null, but not sure why...
EDIT 2: so I changed some things, inside My CountriesFragment:
I deleted the OnActivityCreated method and initialized the interface rather inside the onCreate like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initializeList();
sender = (InterfaceListItemClickListener) getActivity();
}
Now with this change, I was able to know that the findFragmentById inside my MainActivity is returning me a null. now, the way I am displaying this fragment is by using a ViewPager fragment which holds both fragments. this looks like this:
public class ViewPagerFragment extends Fragment {
private OnFragmentInteractionListener mListener;
public static ViewPager viewPager;
public ViewPagerFragment() {
// Required empty public constructor
}
public static ViewPagerFragment newInstance() {
ViewPagerFragment fragment = new ViewPagerFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().setTitle(null);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_view_pager, container, false);
CustomAdapter adapter = new CustomAdapter(getChildFragmentManager()); //getChildFragmentManager
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPager.setAdapter(adapter);
return view;
}
public class CustomAdapter extends FragmentPagerAdapter {
public CustomAdapter(FragmentManager fm){
super(fm);
}
//position tells the program what fragment we are currently on/displaying
public Fragment getItem(int position){
switch (position){ //notice we don't use breaks on each case, due to the return statement on each.
case 0:return CountriesFragment.newInstance();
case 1: return FavoriteFragment.newInstance();
default: return FavoriteFragment.newInstance();
}
}
public int getCount(){
return 2;
}
}
// 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;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
How would I proceed in this case to finish passing the information?
OnCreateView() is called before OnActivityCreate() thats why your sender is null.Moreover,you must avoid setting or creating any objects in the OnCreateView(). Your fragment should be like this
public class CountriesFragment 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";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
ArrayList<RecycleViewItem> listCountries = new ArrayList<>();
String names[] = {"Thailand", "Venezuela", "Sweden"};
int images[] = {R.drawable.thailand, R.drawable.venezuela, R.drawable.sweden};
RecyclerView myRecyclerView;
InterfaceListItemClickListener sender;
public CountriesFragment() {
// Required empty public constructor
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
sender = (InterfaceListItemClickListener) getActivity();
myRecyclerView.setHasFixedSize(true);
LinearLayoutManager myLayoutManager = new LinearLayoutManager(getActivity());
myLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
ListsForFragments.populateCountriesList();
if (ListsForFragments.countriesList.size() > 0 & myRecyclerView != null) {
myRecyclerView.setAdapter(new MyAdapter(ListsForFragments.countriesList, sender));
}
myRecyclerView.setLayoutManager(myLayoutManager);
}
public static CountriesFragment newInstance(String param1, String param2) {
CountriesFragment fragment = new CountriesFragment();
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);
}
initializeList();
}
public void initializeList(){
listCountries.clear();
for(int i = 0; i < names.length; i++){
RecycleViewItem item = new RecycleViewItem();
item.setCardName(names[i]);
item.setImageResourceID(images[i]);
item.setIsFav(0);
item.setIsTurned(0);
listCountries.add(item);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_countries, container, false);
myRecyclerView = (RecyclerView) view.findViewById(R.id.recycleView);
return view;
}
// 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;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
I was following this tutorial on SQLite: https://www.youtube.com/watch?v=3k3CunDZpFk&list=PLshdtb5UWjSrEUEKlfHwqQtYu2HxtCwu_&index=8
I'm attempting to do what he did, but from a fragment. I'm having trouble understanding the context error I get. Can anyone explain it to me?
If you need further information please don't hesitate to ask.
Thank you for your time.
10-18 17:33:16.860 7384-7384/com.example.michael.rogplayer E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.michael.rogplayer, PID: 7384
java.lang.ClassCastException: android.view.ContextThemeWrapper cannot be cast to android.app.Activity
at com.example.michael.rogplayer.BackgroundTask.<init>(BackgroundTask.java:20)
at com.example.michael.rogplayer.CreateNewChar_Fragment$1.onClick(CreateNewChar_Fragment.java:98)
Line 20: activity = (Activity) ctx;
Line 98: BackgroundTask backgroundTask = new BackgroundTask(getView().getContext());
Here's CreateNewChar_Fragment.java
public class CreateNewChar_Fragment extends DialogFragment {
private static Activity scanForActivity(Context cont) {
if (cont == null)
return null;
else if (cont instanceof Activity)
return (Activity)cont;
else if (cont instanceof ContextWrapper)
return scanForActivity(((ContextWrapper)cont).getBaseContext());
return null;
}
EditText name;
Button CANCEL, SAVE;
String NAME;
Context CTX;
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public static CreateNewChar_Fragment newInstance(String param1, String param2) {
CreateNewChar_Fragment fragment = new CreateNewChar_Fragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public CreateNewChar_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) {
getDialog().setTitle("State your name!");
return inflater.inflate(R.layout.fragment_create_new_char_, container, false);
}
public void onViewCreated(View container, Bundle savedInstanceState) {
super.onViewCreated(container, savedInstanceState);
CTX = container.getContext();
SAVE = (Button) getView().findViewById(R.id.save);
CANCEL = (Button) getView().findViewById(R.id.cancel);
name = (EditText) getView().findViewById(R.id.name);
NAME = name.getText().toString();
SAVE.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (TextUtils.isEmpty(name.getText())) {
Toast.makeText(getView().getContext(), "Are you mute!?!?! State your name!!!",
Toast.LENGTH_LONG).show();
} else {
BackgroundTask backgroundTask = new BackgroundTask(getView().getContext());
backgroundTask.execute("add_info", NAME);
getDialog().dismiss();
}
}
});
CANCEL.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getDialog().dismiss();
}
});
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
public void onFragmentInteraction(Uri uri);
}
}
Here's BackgroundTask.java
public class BackgroundTask extends AsyncTask <String,CharacterDisplay,String> {
Context ctx;
CharacterAdapter characterAdapter;
Activity activity;
ListView listView;
BackgroundTask(Context ctx) {
this.ctx = ctx;
activity = (Activity) ctx;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String method = params[0];
DatabaseOperations databaseOperations = new DatabaseOperations(ctx);
if (method.equals("add_info")) {
String name = params[1];
SQLiteDatabase db = databaseOperations.getWritableDatabase();
databaseOperations.putInfo(db, name);
return "One row inserted";
} else if (method.equals("get_info")) {
listView = (ListView) activity.findViewById(R.id.char_list);
SQLiteDatabase db = databaseOperations.getReadableDatabase();
Cursor cursor = databaseOperations.getInfo(db);
characterAdapter = new CharacterAdapter(ctx, R.layout.display_character_row);
String name;
while (cursor.moveToNext()) {
name = cursor.getString(cursor.getColumnIndex(TableData.TableInfo.NAME));
CharacterDisplay characterDisplay = new CharacterDisplay(name);
publishProgress(characterDisplay);
}
return "get_info";
}
return null;
}
#Override
protected void onProgressUpdate(CharacterDisplay... values) {
characterAdapter.add(values[0]);
}
#Override
protected void onPostExecute(String result) {
if (result.equals("get_info")) {
listView.setAdapter(characterAdapter);
} else {
Toast.makeText(ctx,result, Toast.LENGTH_LONG).show();
}
}
}
Here's CharacterDisplay.java
public class CharacterDisplay {
private String name;
public CharacterDisplay(String name) {
this.setName(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Here's CharacterAdapter.java
public class CharacterAdapter extends ArrayAdapter {
List list = new ArrayList();
public CharacterAdapter(Context context, int resource) {
super(context, resource);
}
public void add(Character object) {
list.add(object);
super.add(object);
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
CharacterHolder characterHolder;
if(row == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.display_character_row, parent, false);
characterHolder = new CharacterHolder();
characterHolder.tx_name = (TextView) row.findViewById(R.id.char_name);
row.setTag(characterHolder);
} else {
characterHolder = (CharacterHolder) row.getTag();
}
CharacterDisplay characterDisplay = (CharacterDisplay) getItem(position);
characterHolder.tx_name.setText(characterDisplay.getName().toString());
return row;
}
static class CharacterHolder {
TextView tx_name;
}
}
Activity extends ContextThemeWrapper so the cast exception is caused because your ContextThemeWrapper is not an instance of an Activity. It might be another subclass or a ContextThemeWrapper by itself.
To get an Activity context inside a fragment you can use getActivity() instead of getView().getContext()
I have MainActivity which has FragmentTabHost with several tabs. Each fragment in tab can be replaced with another fragment, so if we navigate back, we will see first displayed fragment for this tab (own stack for each tab). I have a quite working solution.
The below example demonstrates TabHost with 2 tabs and fragment classes for the first tab.
Is there any simpler, better or more elegant way to achieve this result?
AbstractPrimaryFragment.java. This class is a root fragment class that replaces fragments inside it. Other tab fragment classes can extend this superclass.
public abstract class AbstractPrimaryFragment extends Fragment {
// Simple framelayout.
private static final int RES_ID = R.layout.primary_fragment_layout;
protected static final int CONTENT_LAYOUT_ID = R.id.primary_fragment_layout;
protected Fragment mActiveFragment;
public AbstractPrimaryFragment()
{
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(RES_ID, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
// Check if active fragment is in layout, if not, make default fragment for this tab.
mActiveFragment = getChildFragmentManager().findFragmentById(CONTENT_LAYOUT_ID);
if (mActiveFragment == null)
{
mActiveFragment = makeDefaultActiveFragment();
String tag = getDefaultFragmentTag();
getChildFragmentManager().beginTransaction().add(CONTENT_LAYOUT_ID, mActiveFragment, tag).commit();
}
}
public boolean onBackPressed()
{
boolean backPressed = false;
final FragmentManager fragmentManager = getChildFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 0)
{
fragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener()
{
#Override
public void onBackStackChanged()
{
mActiveFragment = fragmentManager.findFragmentById(CONTENT_LAYOUT_ID);
fragmentManager.removeOnBackStackChangedListener(this);
}
});
fragmentManager.popBackStack();
backPressed = true;
}
return backPressed;
}
protected abstract Fragment makeDefaultActiveFragment();
protected abstract String getDefaultFragmentTag(); }
Tab1PrimaryFragment.java
public class Tab1PrimaryFragment extends AbstractPrimaryFragment implements OnTab1Fragment1Listener {
private static final String FRAGMENT1_TAG = "tab1_fragment1";
private static final String FRAGMENT2_TAG = "tab2_fragment2";
#Override
protected Fragment makeDefaultActiveFragment()
{
return new Tab1Fragment1();
}
#Override
protected String getDefaultFragmentTag()
{
return FRAGMENT1_TAG;
}
#Override
public void onTab1Fragment1ButtonClick(Tab1Fragment1 tab1Fragment1)
{
Tab1Fragment2 tab1Fragment2 = new Tab1Fragment2();
getChildFragmentManager().beginTransaction().replace(CONTENT_LAYOUT_ID, tab1Fragment2, FRAGMENT2_TAG).addToBackStack(tab1Fragment1.getTag()).commit();
mActiveFragment = tab1Fragment2;
}}
Tab1Fragment1.class (default active fragment)
public class Tab1Fragment1 extends Fragment {
public interface OnTab1Fragment1Listener
{
public void onTab1Fragment1ButtonClick(Tab1Fragment1 tab1Fragment1);
}
private OnTab1Fragment1Listener mOnTab1Fragment1Listener;
public void setOnTab1Fragment1Listener(OnTab1Fragment1Listener onTab1Fragment1Listener)
{
mOnTab1Fragment1Listener = onTab1Fragment1Listener;
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Fragment parentFragment = getParentFragment();
if (parentFragment != null && parentFragment instanceof OnTab1Fragment1Listener)
{
mOnTab1Fragment1Listener = (OnTab1Fragment1Listener) parentFragment;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Button button = new Button(getActivity());
button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
if(mOnTab1Fragment1Listener != null)
{
mOnTab1Fragment1Listener.onTab1Fragment1ButtonClick(Tab1Fragment1.this);
}
}
});
return button; }}
Tab1Fragment2.java. Dummy fragment. This fragment is displayed when onTab1Fragment1ButtonClick is called.
public class Tab1Fragment2 extends Fragment {}
And MainActivity.java
public class MainActivity extends FragmentActivity {
private static final int RES_ID = R.layout.main_activity;
private static final int TAB_CONTENT_ID = android.R.id.tabcontent;
private static final int TABHOST_ID = android.R.id.tabhost;
private static final String TAB1_PRIMARY_FRAGMENT_TAG = "tab1_primary_fragment";
private static final String TAB2_PRIMARY_FRAGMENT_TAG = "tab2_primary_fragment"
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle bundle)
{
super.onCreate(bundle);
setContentView(RES_ID);
initializeTabHost();
}
private void initializeTabHost()
{
mTabHost = (FragmentTabHost) findViewById(TABHOST_ID);
mTabHost.setup(this, getSupportFragmentManager(), TAB_CONTENT_ID);
LayoutInflater inflater = LayoutInflater.from(this);
mTabHost.addTab(mTabHost.newTabSpec(TAB1_PRIMARY_FRAGMENT_TAG).setIndicator(inflater.inflate(R.layout.smth1, null)), Tab1PrimaryFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec(TAB2_PRIMARY_FRAGMENT_TAG).setIndicator(inflater.inflate(R.layout.smth2, null)), Tab2PrimaryFragment.class, null);
}
#Override
public void onBackPressed()
{
Fragment fragment = getSupportFragmentManager().findFragmentById(TAB_CONTENT_ID);
if (fragment != null && fragment instanceof AbstractPrimaryFragment)
{
if (((AbstractPrimaryFragment) fragment).onBackPressed())
{
return;
}
}
super.onBackPressed();
}}