can't add item to my recycler view from another fragment - android

I have an activity that has five fragments, One fragments is the notification fragment that has a recycler view where notification should be populating upon receiving them. now i have a function that add the items to the recycler view but when i try add it from another fragment it throws and null reference error.
Here is the fragment where there is the recycler and function to add the items on the recyclerview
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
final View v = inflater.inflate (R.layout.fragment_notificationcict, container, false);
notimodels = new ArrayList<> ();
RecyclerView mRecyclerView = v.findViewById (R.id.notificationsRecycler);
mRecyclerView.setHasFixedSize (true);
mLayoutManager = new LinearLayoutManager (getContext ());
mAdapter = new NotificationAdapter (notimodels);
mRecyclerView.setLayoutManager (mLayoutManager);
mRecyclerView.setAdapter (mAdapter);
}
public void addItem(NotificationModel n)
{
notimodels = new ArrayList<> ();
notimodels.add (n);
mAdapter.notifyItemInserted (notimodels.size () -1);
}
On the second fragment that adds items to the notification fragment
NotificationFragmentCict fragment = new NotificationFragmentCict ();
NotificationModel model = (new NotificationModel (R.drawable.logo, "OCApp", "Where are yiu.", "min"));
fragment.addItem (model);
Here is the Error
rocess: com.univibezstudios.ocappservice.ocapp, PID: 27625
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView$Adapter.notifyItemInserted(int)' on a null object reference
at com.univibezstudios.ocappservice.ocapp.Fragments.NotificationFragmentCict.addItem(NotificationFragmentCict.java:99)
at com.univibezstudios.ocappservice.ocapp.Fragments.AccountFragmentCict$4$1$1.onDataChange(AccountFragmentCict.java:374)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database##19.2.1:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database##19.2.1:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database##19.2.1:55)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6803)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:497)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

See This is Fragment A
package com.codinginflow.fragmentcommunicationexample;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
public class FragmentA extends Fragment {
private FragmentAListener listener;
private EditText editText;
private Button buttonOk;
public interface FragmentAListener {
void addItemsToFragmentB();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_a, container, false);
editText = v.findViewById(R.id.edit_text);
buttonOk = v.findViewById(R.id.button_ok);
buttonOk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addItemsToFragmentB();
});
return v;
}
public void updateEditText(CharSequence newText) {
editText.setText(newText);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof FragmentAListener) {
listener = (FragmentAListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement FragmentAListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
}
This is Fragment B
package com.codinginflow.fragmentcommunicationexample;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
public class FragmentB extends Fragment {
private FragmentBListener listener;
private EditText editText;
private Button buttonOk;
public interface FragmentBListener {
addItemsToFragmentA();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_b, container, false);
editText = v.findViewById(R.id.edit_text);
buttonOk = v.findViewById(R.id.button_ok);
buttonOk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addItemsToFragmentA();
}
});
return v;
}
public void updateEditText(CharSequence newText) {
editText.setText(newText);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof FragmentBListener) {
listener = (FragmentBListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement FragmentBListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
}
This is an Activity in which u r going to add items to your recycler view
package com.codinginflow.fragmentcommunicationexample;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity implements FragmentA.FragmentAListener, FragmentB.FragmentBListener {
private FragmentA fragmentA;
private FragmentB fragmentB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentA = new FragmentA();
fragmentB = new FragmentB();
getSupportFragmentManager().beginTransaction()
.replace(R.id.container_a, fragmentA)
.replace(R.id.container_b, fragmentB)
.commit();
}
#Override
public void addItemsToFragmentA() {
fragmentB.updateEditText(input);
}
#Override
public void addItemsToFragmentB() {
fragmentA.updateEditText(input);
}
}

Related

Android: How to return to ParentFragment with RecyclerView.Adapter from a DialogFragment called that was called from the RecyclerView

I have a Fragment "MyParentFragment" (in a tabbed fragment in a NavigationDrawer Activity). In MyParentFragment sits a RecyclerView, fed from a SQLiteDB. When clicked on a RecyclerView item, a custom DialogFragment "myDialogFragment" is opened and a bundle containing a custom Parcelable object is passed. The DialogFragment contains a button, that does stuff (later).
So far, everything is working.
Now, when I click the button in the DialogFragment, after it did its stuff, I want to return to the DialogFragments parent fragment "MyParentFragment" that has the RecyclerView, if possible showing the RecyclerView item, that was last clicked. Everything I tried so far, crashed the app.
The DialogFragment does not have to return anything (currently a String), I can work around that, but it would be great if it could return a custom object of another class.
Min SDK version is 21, current target version is 32.
This is my first Android Project. I know some Java, but Android development, interfaces, backstacks and such are new to me. I hope you can help me.
This is MyParentFragment:
package com.example.utnmpg;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.utnmpg.Database.DataBaseHelper;
import com.example.utnmpg.Database.VPeopleModel;
import com.example.utnmpg.RecView.PeopleRecycleViewAdapter;
import java.util.ArrayList;
public class MyParentFragment extends Fragment
implements View.OnClickListener, MyDialogFragment.DialogListener{
private DataBaseHelper dataBaseHelper;
private ArrayList<VPeopleModel> peopleList;
private RecyclerView MyRecyclerView;
private RecyclerView.Adapter mAdapter;
public MyParentFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dataBaseHelper = new DataBaseHelper(getContext());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_myparrent,
container, false);
MyRecyclerView = view.findViewById(R.id.rv_peopleList);
MyRecyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(view.getContext());
MyRecyclerView.setLayoutManager(layoutManager);
mAdapter = new PeopleRecycleViewAdapter(peopleList, view.getContext());
MyRecyclerView.setAdapter(mAdapter);
return view;
}
#Override
public void onClick(View v) {
}
#Override
public void onFinishNoDialog(String inputText) {
Toast.makeText(getContext(), inputText, Toast.LENGTH_SHORT).show();
}
}
This is the RecyclerView in MyParentFragment:
package com.example.utnmpg.RecView;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.RecyclerView;
import com.example.utnmpg.Database.VPeopleModel;
import com.example.utnmpg.MyDialogFragment;
import com.example.utnmpg.R;
import java.util.ArrayList;
public class PeopleRecycleViewAdapter
extends RecyclerView.Adapter<PeopleRecycleViewAdapter.MyViewHolder>
implements View.OnClickListener, MyDialogFragment.DialogListener {
private ArrayList<VPeopleModel> peopleList;
private Context context;
public PeopleRecycleViewAdapter(ArrayList<VPeopleModel> peopleListParam, Context contextP) {
this.peopleList = peopleListParam;
this.context = contextP;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.one_person,
parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.tvName.setText(peopleList.get(position).toStringName());
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyDialogFragment myDialogFragment = new MyDialogFragment();
Bundle bundle = new Bundle();
bundle.putParcelable("people", peopleList.get(holder.getBindingAdapterPosition()));
myDialogFragment.setArguments(bundle);
FragmentManager fragmentManager = ((AppCompatActivity) context).getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment prev = fragmentManager.findFragmentByTag("people");
if (prev != null) {
fragmentTransaction.remove(prev);
}
fragmentTransaction.addToBackStack(null);
myDialogFragment.show(fragmentManager, "people");
}
});
}
#Override
public int getItemCount() {
return peopleList.size();
}
#Override
public void onClick(View v) { }
#Override
public void onFinishNoDialog(String returnText) {
Toast.makeText(context, returnText, Toast.LENGTH_SHORT).show();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView tvName;
private ConstraintLayout parentLayout;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tv_ndia_name);
//onePersonLayout is the id defined in one_person.xml
parentLayout = itemView.findViewById(R.id.onePersonLayout);
}
}
}
And the DialogFragment:
package com.example.utnmpg;
import android.app.Dialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import com.example.utnmpg.Database.DataBaseHelper;
import com.example.utnmpg.Database.VPeopleModel;
public class MyDialogFragment extends DialogFragment {
private TextView tvName;
private Button btnOK;
private DataBaseHelper dataBaseHelper;
public MyDialogFragment() {
}
public static MyDialogFragment newInstance(VPeopleModel peopleModel) {
MyDialogFragment fragment = new MyDialogFragment();
Bundle args = new Bundle();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dataBaseHelper = new DataBaseHelper(getContext());
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return super.onCreateDialog(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my_dialog, container, false);
Bundle bundle = getArguments();
VPeopleModel peopleModel = bundle.getParcelable("people");
tvName = view.findViewById(R.id.tv_ndia_name);
btnOK = view.findViewById(R.id.btn_ndia_ok);
tvName.setText(peopleModel.getName());
btnOK.setOnClickListener(item -> {
Toast.makeText(getContext(), "klicked", Toast.LENGTH_SHORT).show();
String success = "yes";
DialogListener dialogListener = (DialogListener) getParentFragment();
dialogListener.onFinishNoDialog(success);
dismiss();
});
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onDestroyView() {
super.onDestroyView();
}
#Override
public void onResume() {
super.onResume();
}
public interface DialogListener {
void onFinishNoDialog(String inputText);
}
}

Communication between two fragments with interface

My app have one activity A and two fragments F1 and F2.
One clicking button in F1, the F1 is replaced by F2.
I want to transfer data in F1 to F2. For that I implemented the interface in F1 and override its method in A.
But when sending the data from A to F2, my reference(sFragment in code A) to the F2 remains null,due to which data is not sent to F2. I am getting reference to the F2 using TAG provided while replacing F1 by F2.
Does it have something to do with the lifecycle like when I am trying to get reference to the F2 it hasn't yet created?
F1
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.form_fragment1,container,false);
nextB = (Button) v.findViewById(R.id.f1Next);
nextB.setOnClickListener(this);
return v;
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.f1Next:
SFragment fragment = new SFragment();
FragmentManager mManager = getFragmentManager();
FragmentTransaction mTransaction = mManager.beginTransaction();
mTransaction.replace(R.id.fragment_container,fragment,"SecondF"); // SecondF
mTransaction.addToBackStack(null); // this is required to move to the previous fragment
mTransaction.commit();
commListener.PlaceName(data1,data2); //passing value to activity
break;
}
}
interface CommBridge{
void PlaceName(String data1,String data2);
}
#Override
public void onAttach(Context context){
super.onAttach(context);
if (context instanceof CommBridge){
commListener= (CommBridge) context;
}
}
}
A
#Override
public void PlaceName(String data1, String data2) {
SFragment sFragment=(SFragment) getFragmentManager().findFragmentByTag("SecondF");
if (sFragment != null && sFragment.isInLayout()){
Log.d("STATE","1");
sFragment.setPlace(data1,data2);
}else{
Log.d("STATE","2"); // this is always the case
}
F2
public class SFragment extends Fragment {
String Place2,Place1;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.form_fragment2,container,false);
return v;
}
void setPlace(String data1, String data2){
place1 = data1;
place2 = data2;
}
}
Let the activity be responsible for handling the onClick event of the Fragment. See the example below.
Activity:
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
public class MainActivity extends AppCompatActivity implements Fragment1.CommBridge {
private Fragment1 fragment1 = new Fragment1();
private Fragment2 fragment2 = new Fragment2();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content, fragment1)
.commit();
}
#Override
public void onButtonClicked(String data1, String data2) {
fragment2.setData(data1, data2);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content, fragment2)
.commit();
}
}
Fragment1:
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
public class Fragment1 extends Fragment {
interface CommBridge {
void onButtonClicked(String data1, String data2);
}
private CommBridge handler;
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof CommBridge) {
handler = (CommBridge) context;
}
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment1, container, false);
Button button = (Button) view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handler.onButtonClicked("Data1", "Data2");
}
});
return view;
}
}
Fragment2
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class Fragment2 extends Fragment {
private String data1;
private String data2;
public void setData(String data1, String data2) {
this.data1 = data1;
this.data2 = data2;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment2, container, false);
TextView textView = (TextView) view.findViewById(R.id.textView);
textView.setText(data1 + "\n" + data2);
return view;
}
}
I would recommend putting the code for replacing the fragment in your Activity and put the values which should be passed to SFragment() in its arguments directly:
SFragment newFragment = new SFragment();
Bundle args = new Bundle();
args.putString("place1", data1);
args.putString("place2", data1);
newFragment.setArguments(args);
You could get them in SFragment#onCreateView()
String place1 = getArguments().getString("place1");
Also have a look here: https://developer.android.com/training/basics/fragments/communicating.html

Android - Communicating between fragments, adapter is null

I've been looking for an answer for a while now, but I haven't been able to find the same situation, so I'll try asking it here.
I'm currently creating an app with an Activity, 2 fragments and viewpager functionality. Fragment 1 has a button that will update the list on fragment 2 (the usual way, frag 1 -> activity -> frag 2) and when it reaches that method and calls notifyDataSetChanged it crashes because the adapter is null. Apparently the adapter is null and the existing List to fill the listview is empty (which isn't a huge problem because it gets filled again, but I'd like to keep the original items).
How can I update my list and why is my adapter null?
My code:
MainActivity
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
public class MainActivity extends FragmentActivity implements FirstFragment.OnUpdatedListListener {
private ViewPager viewPager;
private TestAdapter mAdapter;
//Lifecycle functions
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.TestPager);
mAdapter = new TestAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
#Override
public void onPageSelected(int position) {}
#Override
public void onPageScrollStateChanged(int state) {}
});
}
#Override
public void onListUpdated() {
logcat("Click received in main");
SecondFragment sf = SecondFragment.newInstance();
if (sf == null || !sf.isInLayout()) {
logcat("frag == null || !frag.isInLayout()");
SecondFragment newFragment = SecondFragment.newInstance();
Bundle args = new Bundle();
newFragment.setArguments(args);
android.support.v4.app.FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.second_fragment, newFragment);
transaction.addToBackStack(null);
transaction.commit();
newFragment.receiver();
} else {
logcat("frag bestaat");
sf.receiver();
}
}
}
ListItemAdapter:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.List;
public class ListItemAdapter extends ArrayAdapter<ListItem> {
private final Context context;
private List<ListItem> items;
public ListItemAdapter(Context context, int resource, List<ListItem> values) {
super(context, R.layout.list_items, values);
this.context = context;
this.items = values;
}
private static class ViewHolder {
TextView tvName;
TextView tvDescription;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.list_items, parent, false);
ViewHolder viewholder = new ViewHolder();
viewholder.tvName = (TextView) rowView.findViewById(R.id.tvName);
viewholder.tvDescription = (TextView) rowView.findViewById(R.id.tvDescription);
rowView.setTag(viewholder);
}
ViewHolder holder = (ViewHolder) rowView.getTag();
holder.tvName.setText(items.get(position).getName());
holder.tvDescription.setText(items.get(position).getDescription());
return rowView;
}
}
SecondFragment:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class SecondFragment extends Fragment {
private final static String TAG = "SecondFragment";
private List<ListItem> items = new ArrayList<>();
private ListView lv;
private ListItemAdapter adapter;
public SecondFragment() {}
public static SecondFragment newInstance() {
Bundle args = new Bundle();
secondFragment.setArguments(args);
return secondFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
items.add(new ListItem(1, "Willem", "Willemkeurige beschrijving"));
items.add(new ListItem(2, "Jos", "De Klos"));
items.add(new ListItem(3, "Leo", "Pold"));
adapter = new ListItemAdapter(getActivity(), 0, items);
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_second, container, false);
lv = (ListView) v.findViewById(R.id.lvSecond);
lv.setAdapter(adapter);
return v;
}
public void receiver() {
items.add(new ListItem(4, "Willem2", "Willemkeurige beschrijving"));
items.add(new ListItem(5, "Jos2", "De Klos"));
items.add(new ListItem(6, "Leo", "Pold3"));
adapter.notifyDataSetChanged();
}
}
You can try this:
In MyActivity add:
public class MyActivity extends FragmentActivity {
//...
private ListItemAdapter mAdapter;
public ListItemAdapter getAdapter(){
if (mAdapter==null){
mAdapter = new ListItemAdapter();
}
return mAdapter;
}
}
In your Fragment you can get the Adapter using:
((MyActivity)getActivity()).getAdapter();
This way you can "share" your Adapter.
The problem is that your calling receiver() before the fragment has been added. The fragment has its own lifecycle, so there is not guarantee that onCreate and onCreateView has been called. This is why your adapter is null. To fix this you can do:
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_second, container, false);
lv = (ListView) v.findViewById(R.id.lvSecond);
lv.setAdapter(adapter);
receiver();
return v;
}
public void receiver(){
//add your strings as normal
if(adapter != null){
adapter.notifyDataSetChanged();
}
}

Can't add fragments - android

I'm trying to build a simple application that displays two fragments. The first fragment is displayed by default. It contains a list of names which you can choose and when you click on one of the items, it supposes to display a second fragment with a text view, displaying the name you have chosen.
The problem is everytime I click one of the names on the list, it throws me a NullPointerException. I really don't know what could be the problem.
Here are the codes( The app contains three class - two fragments and one activity. The FriendsF fragment is the list fragment and it performs well. The second fragment is FeedFragment and onitemclick it should display the name that was clicked)
FriendsF fragment:
package com.example.fragmentsexcersize;
import android.app.Activity;
import android.app.ListFragment;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class FriendsF extends ListFragment {
private static final String[] FRIENDS = { "ladygaga", "msrebeccablack",
"taylorswift13" };
public interface SelectionListener {
public void onItemSelected(int position);
}
private SelectionListener mCallback;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? android.R.layout.simple_list_item_activated_1
: android.R.layout.simple_list_item_1;
setListAdapter(new ArrayAdapter<String>(getActivity().getBaseContext(), layout, FRIENDS));
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (SelectionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement SelectionListener");
}
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (isInTwoPaneMode()) {
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
}
#Override
public void onListItemClick(ListView l, View view, int position, long id) {
mCallback.onItemSelected(position);
}
private boolean isInTwoPaneMode() {
return getFragmentManager().findFragmentById(R.id.tweets) != null;
}
}
FeedFragment:
package com.example.fragmentsexcersize;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class FeedFragment extends Fragment{
private TextView mTextView;
private static final String[] data = { "ladygaga", "msrebeccablack",
"taylorswift13" };
public FeedFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tweet_view, container, false);
mTextView = (TextView) rootView.findViewById(R.id.tweet_view);
return rootView;
}
public void updateFeedDisplay(int position) {
mTextView.setText(data[position]);
}
}
MainActivity:
package com.example.fragmentsexcersize;
import android.app.Activity;
import android.app.FragmentManager;
import android.os.Bundle;
import android.app.FragmentTransaction;
public class MainActivity extends Activity implements FriendsF.SelectionListener{
private FriendsF mFriendsFragment;
private FeedFragment mFeedFragment;
private FragmentManager fragMana;
private FragmentTransaction transaction;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFriendsFragment = new FriendsF();
fragMana = getFragmentManager();
transaction = fragMana.beginTransaction();
transaction.add(R.id.friends, mFriendsFragment);
transaction.commit();
}
private boolean isInTwoPaneMode() {
return findViewById(R.id.tweets) == null;
}
public void onItemSelected(int position) {
if (mFeedFragment == null)
mFeedFragment = new FeedFragment();
if (!isInTwoPaneMode()) {
transaction = fragMana.beginTransaction();
transaction.add(R.id.tweets, mFeedFragment);
transaction.commit();
}
mFeedFragment.updateFeedDisplay(position);
}
}
Make the following changes to your source:
MainActivity
public void onItemSelected(int position) {
Bundle bundle = new Bundle();
if (mFeedFragment == null)
mFeedFragment = new FeedFragment();
if (!isInTwoPaneMode()) {
bundle.putInt("POSITION", position);
mFeedFragment.setArguments(bundle);
transaction = fragMana.beginTransaction();
transaction.replace(R.id.tweets, mFeedFragment);
transaction.commit();
}
}
FeedFragment
private TextView mTextView;
private static final String[] data = { "ladygaga", "msrebeccablack",
"taylorswift13" };
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
View rootView = inflater.inflate(R.layout.tweet_view, container, false);
mTextView = (TextView) rootView.findViewById(R.id.tweet_view);
int mPosition = getArguments().getInt("POSITION", 0);
mTextView.setText(data[mPosition]);
return rootView;
}

Listview inside a fragment class of a Viewpager

I have a ViewPager setup with 3 fragment Classes, and a pageadapter class.
MainActivity class
package com.example.swipeview;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
public class MainActivity extends FragmentActivity {
ViewPager viewpager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewpager = (ViewPager) findViewById(R.id.viewpagers);
com.example.swipeview.PagerAdapter padapter = new com.example.swipeview.PagerAdapter(getSupportFragmentManager());
viewpager.setAdapter(padapter);
}
}
PageAdapter class
package com.example.swipeview;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class PagerAdapter extends FragmentPagerAdapter {
public PagerAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
#Override
public Fragment getItem(int arg0) {
// TODO Auto-generated method stub
switch(arg0){
case 0:
return new FragmentOne();
case 1:
return new FragmentTwo();
case 2:
return new FragmentThree();
default:
break;
}
return null;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return 3;
}
}
and my first FragmentClass as an example
package com.example.swipeview;
import com.example.swipeview.R;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState){
return inflater.inflate(R.layout.fragment_one_layout, container, false);
}
}//end of class
I've tried my usual methods for creating a listview inside of an Activity class but that doesn't work with the fragment class. I was wondering if anyone could show me how to code a listview into a fragment class.
An example with a custom adapter (using a List as source):
public class ItemsFragment extends Fragment {
/* Must be populated later. */
private final List<Item> items = new ArrayList<>();
private ItemAdapter adapter;
private ListView listView = null;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_items_list, container, false);
adapter = new ItemAdapter(this.getActivity(), items);
listView = (ListView) layout.findViewById(R.id.listview_items);
return layout;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Item currentItem = adapter.getItem(position);
// (...)
}
});
}
/* (...) */
}

Categories

Resources