I created a TabLayout with one MainActivity and two fragments in Android.
But how do you get the second Fragment to receive the button event and call the first Fragment function?
I tried the following but it does not work and I ask.
public interface CustomSearchPOI {
void requestSearch(String query);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
customSearchPOI = (CustomSearchPOI)context;
} catch (ClassCastException ex) {
throw new ClassCastException(context.toString() + "must implement CustomSearchPOI");
}
}
Second Fragment Code
if(info_cursor != null) {
info_cursor.moveToFirst();
while(!info_cursor.isAfterLast()) {
if(info_cursor.getInt(0) == id) {
out_subject.setText(info_cursor.getString(1));
out_college.setText(info_cursor.getString(2));
out_classroom.setText(info_cursor.getString(3));
break;
}
info_cursor.moveToNext();
}
}
choice_dialog.setPositiveButton(getString(R.string.Location_navigate), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
TabsFragment.viewPager.setCurrentItem(0);
customSearchPOI.requestSearch(out_college.getText().toString());
}
});
choice_dialog.setNegativeButton(getString(R.string.tt_modify), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
update_timetable_dialog(id);
}
});
choice_dialog.show();
Call function Code
#Override
public void requestSearch(String query) {
String FRAGMENT_TAG = "LOCATION_TAG";
Fragment fragment = new MapFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(fragment, FRAGMENT_TAG).commitAllowingStateLoss();
try {
((MapFragment)getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG)).searchPOI(query);
} catch(NullPointerException ex) {
ex.printStackTrace();
Log.d("[TAG]", fragment.getTag());
}
}
MainActivity Code
public void searchPOI(String query) {
query = Searchcheck(query);
TMapData data = new TMapData();
if(!TextUtils.isEmpty(query)) {
data.findAllPOI(query, new TMapData.FindAllPOIListenerCallback() {
#Override
public void onFindAllPOI(final ArrayList<TMapPOIItem> arrayList) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
tMapView.removeAllMarkerItem();
for (TMapPOIItem poi : arrayList) {
addMarker(poi);
}
if(arrayList.size() > 0) {
TMapPOIItem poi = arrayList.get(0);
moveMap(poi.getPOIPoint().getLatitude(), poi.getPOIPoint().getLongitude());
if(poi.getPOIPoint().getLatitude() > 36.832311 && poi.getPOIPoint().getLongitude() < 127.165038) {
Snackbar.make(coordinatorLayout, getString(R.string.No_place), Snackbar.LENGTH_LONG).show();
if(location_me.getVisibility() != View.INVISIBLE) {
location_me.hide();
}
return;
}
dst = new TMapPoint(poi.getPOIPoint().getLatitude(), poi.getPOIPoint().getLongitude());
searchRoute(src, dst);
}
}
});
}
});
}
}
First Fragment Code (function to call)
According to the Google development documentation, direct communication between fragments and fragments is impossible.
So when I try to call Fragment function from Fragment through Activity, I get NullPointerException error.
I used the try catch syntax to see if there was an error in the tag name or an error in the query, but neither of them was a problem.
FragmentX:
public class MyFragment extends Fragment{
interface MyInterface{
void doSomething();
}
public void someMethodInYourFragment(){
((MyInterface)getContext()).doSomething();//throws ClassCastException if not implemented in Activity
}
}
Class X:
public class MyActivity extends Activity implements MyFragment.MyInterface{
#Override
public void doSomething(){
//do stuff here
}
}
Related
I am working on an app and I am using a custom dialog which extends DialogFragment. This dialog will contain certain field that I want to pass to the parent activity. I tried implementing OnDismissListener but the parameter is a Dialog Interface.
Any Idea?
parent Activity:
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
BreakCreator mDialog = new BreakCreator();
mDialog.show(getSupportFragmentManager(), "start break Creator");
}
});
listener:
#Override
public void onDismiss(DialogInterface dialog) {
Log.d("debug", "in onDismiss");
BreakCreator mBreakCreator = BreakCreator.class.cast(dialog);// This MIGHT not work
//TODO cast and shit
if(!mBreakCreator.isCancelled() ){
int startMinute = mBreakCreator.getStartMinute();
int startHour = mBreakCreator.getStartHour();
int endMinute = mBreakCreator.getEndMinute();
int endHour = mBreakCreator.getEndHour();
String day = mBreakCreator.getDay();
Break mBreak = new Break(new ultramirinc.champs_mood.Time(startHour, startMinute),
new ultramirinc.champs_mood.Time(endHour, endMinute), day);
breakList.add(mBreak);
Log.d("created", "break added");
recyclerView.invalidate();
}else{
Log.d("debug", "is not cancelled");
}
}
Dialog Class:
public void onDismiss(final DialogInterface dialog) {
super.onDismiss(dialog);
final Activity activity = getActivity();
if (activity instanceof DialogInterface.OnDismissListener) {
((DialogInterface.OnDismissListener) activity).onDismiss(dialog);
}
}
Use a custom listener, below is an example on how this could be implemented. This is also explained in the Android Developer Guide.
public class CustomDialog extends DialogFragment {
public interface CustomListener{
void onMyCustomAction(CustomObject co);
}
private CustomListener mListener;
public void setMyCustomListener(CustomListener listener){
mListener = listener;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
...
Code to create dialog
...
}
#Override
public void onDismiss(DialogInterface dialog) {
if(mListener != null){
CustomObject o = new CustomObject();
mListener.onMyCustomAction(o);
}
super.onDismiss();
}
}
And when the custom dialog is created, set the listener.
CustomDialog awesomeDialog = new CustomDialog();
awesomeDialog.setMyCustomListener(new CustomDialog.CustomListener() {
#Override
public void onMyCustomAction(CustomObject o){
Log.i("TAG",o.toString());
}
});
I've found several questions about this, none of which help me. Each question relates to other functions and views I don't implement in my fragments, and the issue is not that I need to swap my method getting the FragmentManager to getChildFragmentManager() anywhere in my fragments, because I don't need to get a FragmentManager there.
I'm guessing that my issue stems from the fragments and not the FragmentTabHost in the main activity, but I am not really sure. At all. All I know is that when you page between tabs, the adapter content disappears, but not the fragment itself. All views are still functional, so the functionality of each fragment remains intact.
This issue popped up only after I added a tab change listener for when to initialize the adapter for my chat fragment.
Note that the content of the tabs is fine when they are first initialized, but when you return to the tab the content in the adapters empty. This means that the tab that is not initialized yet when the FragmentTabHost is created, the hidden tabs haven't been initialized yet, so they will still work the first time you page over to them.
Through debugging, I can see that this issue occurs when the transition happens, and all adapters will remain empty for the duration of the usage session. I put this snippit of code before the initial checks in my tabHost.setOnTabChangedListener call:
//Before paging back to an initialized tab for the first time, the adapters of the initialized tab is populated.
Log.d("test", "pre");
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//At this point, the adapter is empty.
Log.d("test", "post");
}
}, 50);
The two fragments are as follows:
public class GroupTasksFragment extends Fragment {
public ArrayAdapter<String> adapter;
private Context context;
public ListView taskListView;
public GroupTasksFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_group_tasks, container, false);
taskListView = (ListView) rootView.findViewById(R.id.tasksList);
adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, new ArrayList<String>());
taskListView.setAdapter(adapter);
return rootView;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
#Override
public void onDetach() {
super.onDetach();
}
}
public class GroupChatFragment extends Fragment{
public ArrayAdapter<String> adapter;
private Context context;
public ListView chatListView;
public GroupChatFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_group_chat, container, false);
chatListView = (ListView) rootView.findViewById(R.id.chatList);
adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, new ArrayList<String>());
chatListView.setAdapter(adapter);
return rootView;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
#Override
public void onDetach() {
super.onDetach();
}
}
The main activity with the FragmentTabHost (I have excluded methods that just take input and send content to PubNub):
public class GroupContentActivity extends AppCompatActivity {
private GroupChatFragment chatFrag;
private GroupTasksFragment taskFrag;
private FragmentTabHost tabHost;
private PubNub connection;
private String groupName;
private String nickName;
private boolean chatFragInitialized = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_group_content);
tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
tabHost.setup(this, getSupportFragmentManager(), android.R.id.tabcontent);
tabHost.addTab(tabHost.newTabSpec("tasks").setIndicator("Tasks"),
GroupTasksFragment.class, null);
tabHost.addTab(tabHost.newTabSpec("chat")
.setIndicator("Chat"), GroupChatFragment.class, null);
groupName = getIntent().getStringExtra("groupName");
nickName = getIntent().getStringExtra("nickName");
PNConfiguration config = new PNConfiguration();
config.setPublishKey(Constants.publishKey);
config.setSubscribeKey(Constants.subscribeKey);
connection = new PubNub(config);
tabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
#Override
public void onTabChanged(String tabId) {
if (!chatFragInitialized && tabId.equals("chat")) {
chatFragInitialized = true;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
chatFrag = (GroupChatFragment) getSupportFragmentManager().findFragmentByTag("chat");
connection.history()
.channel(groupName)
.count(50)
.async(new PNCallback<PNHistoryResult>() {
#Override
public void onResponse(PNHistoryResult result, PNStatus status) {
for (PNHistoryItemResult item : result.getMessages()) {
final String[] sForm = item.getEntry().getAsString().split(">>>>");
String m = "";
if (sForm.length > 2) {
for (int x = 1; x < sForm.length; x++) {
m += sForm[x];
}
} else {
m = sForm[1];
}
final String mCopy = m;
runOnUiThread(new Runnable() {
#Override
public void run() {
switch (sForm[0]) {
case "groupCreated":
chatFrag.adapter.clear();
break;
case "chat":
chatFrag.adapter.add(mCopy);
}
}
});
}
}
});
}
}, 50);
}
}
});
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
taskFrag = (GroupTasksFragment) getSupportFragmentManager().findFragmentByTag("tasks");
connection.history()
.channel(groupName)
.count(50)
.async(new PNCallback<PNHistoryResult>() {
#Override
public void onResponse(PNHistoryResult result, PNStatus status) {
for (PNHistoryItemResult item : result.getMessages()) {
final String[] sForm = item.getEntry().getAsString().split(">>>>");
String m = "";
if (sForm.length > 2) {
for (int x = 1; x < sForm.length; x++) {
m += sForm[x];
}
} else {
m = sForm[1];
}
final String mCopy = m;
runOnUiThread(new Runnable() {
#Override
public void run() {
switch (sForm[0]) {
case "addTask":
if (taskFrag.adapter.getPosition(mCopy) < 0) {
taskFrag.adapter.add(mCopy);
}
break;
case "deleteTask":
if (taskFrag.adapter.getPosition(mCopy) >= 0) {
taskFrag.adapter.remove(mCopy);
}
break;
case "groupCreated":
taskFrag.adapter.clear();
break;
}
}
});
}
}
});
connection.addListener(new SubscribeCallback() {
#Override
public void status(PubNub pubnub, PNStatus status) {
if (status.getCategory() == PNStatusCategory.PNUnexpectedDisconnectCategory) {
Toast.makeText(getApplicationContext(), "You were disconnected!", Toast.LENGTH_SHORT).show();
} else if (status.getCategory() == PNStatusCategory.PNConnectedCategory) {
if (status.getCategory() == PNStatusCategory.PNConnectedCategory) {
pubnub.publish().channel(groupName).message("chat>>>><ADMIN> User '" + nickName + "' Connected").async(new PNCallback<PNPublishResult>() {
#Override
public void onResponse(PNPublishResult result, PNStatus status) {
}
});
}
} else if (status.getCategory() == PNStatusCategory.PNReconnectedCategory) {
Toast.makeText(getApplicationContext(), "You were reconnected!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void message(PubNub pubnub, PNMessageResult message) {
final String[] sForm = message.getMessage().getAsString().split(">>>>");
String m = "";
if (sForm.length > 2) {
for (int x = 1; x < sForm.length; x++) {
m += sForm[x];
}
} else {
m = sForm[1];
}
final String mCopy = m;
runOnUiThread(new Runnable() {
#Override
public void run() {
switch (sForm[0]) {
case "chat":
if (chatFragInitialized) {
chatFrag.adapter.add(mCopy);
runOnUiThread(new Runnable() {
#Override
public void run() {
chatFrag.chatListView.setSelection(chatFrag.adapter.getCount() - 1);
}
});
}
break;
case "addTask":
taskFrag.adapter.add(mCopy);
connection.publish().channel(groupName).message("chat>>>><ADMIN> Task '" + mCopy + "' added.").async(new PNCallback<PNPublishResult>() {
#Override
public void onResponse(PNPublishResult pnPublishResult, PNStatus pnStatus) {
}
});
break;
case "deleteTask":
taskFrag.adapter.remove(mCopy);
connection.publish().channel(groupName).message("chat>>>><ADMIN> Task '" + mCopy + "' deleted.").async(new PNCallback<PNPublishResult>() {
#Override
public void onResponse(PNPublishResult pnPublishResult, PNStatus pnStatus) {
}
});
break;
}
}
});
}
#Override
public void presence(PubNub pubnub, PNPresenceEventResult presence) {
}
});
connection.subscribe().channels(java.util.Collections.singletonList(groupName)).execute();
}
}, 100);
}
#Override
public void onDestroy(){
super.onDestroy();
connection.publish().channel(groupName).message("chat>>>><ADMIN> User '" + nickName + "' Logged Out.").async(new PNCallback<PNPublishResult>() {
#Override
public void onResponse(PNPublishResult pnPublishResult, PNStatus pnStatus) {
}
});
connection.disconnect();
Toast.makeText(getApplicationContext(), "Logged out", Toast.LENGTH_SHORT).show();
}
//More Methods
}
Also note that the issue is not that I need to store the FragmentManager instance, as that doesn't do anything.
I found my issue. It turns out that every time a fragment is paged to in the FragmentTabHost, it's createView method is called again, and only that method, so by setting the adapter in the fragment to empty in that view, which I thought was only at the start, I reset the adapter each time.
I fixed this by keeping the adapter content as an instance variable list object that I add or remove strings to/from when I want to change the adapter. DO NOT ALSO PUT THE STRINGS IN THE ADAPTER, updating the list is enough. The list will directly add it to the adapter.
Also note that if you set the initial content outside of the fragment, it may not show when the tabs are first initialized. Just be careful of your statement ordering and when things are called. Fragment construction is funky business.
Then, I set the adapter to whatever is in the list each time the createView method is called.
Can somebody answer this question for me:
For testing purposes I have created an activity with a for loop in which I'm creating 10 AlertDialogs or 10 DialogFragments.
Immediately after the activity is started I'm pressing the home button to send the app in the background.
If I'm running the showDialog() method to create the DialogFragments the app will crash with:
IllegalStateException: Can not perform this action after onSaveInstanceState
this is expected behavior.
But if I run the showAlert() method to create the AlertDialogs and same as before I'm sending the app to the background the app doesn't crash. When I return to the activity I can see all 10 AlertDialogs.
The question is why does the activity state loss happen with DialogFragment and not with AlertDialog?
I am still changing the UI after the activity's state has been saved. The platform on which I have tested is Android 4.4.2
public class Main extends FragmentActivity
{
private FragmentActivity activity = this;
private MyAsynk myAsynk;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
myAsynk = new MyAsynk();
myAsynk.execute();
}
private class MyAsynk extends AsyncTask<Void, Void, Void>
{
private boolean run = false;
public MyAsynk()
{
run = true;
}
#Override
protected Void doInBackground(Void... params)
{
for(int i = 0; i < 10 && run; i++)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
// showAlert("loop " + i);
showDialog("loop " + i);
}
return null;
}
public void stop()
{
run = false;
}
}
#Override
public void onBackPressed()
{
super.onBackPressed();
if(null != myAsynk)
{
myAsynk.stop();
myAsynk = null;
}
}
private void showAlert(final String txt)
{
try
{
Main.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
new AlertDialog.Builder(activity).setMessage(txt)
.setPositiveButton("Ok", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
try
{
if(null != dialog)
{
dialog.dismiss();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
})
.show();
}
});
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void showDialog(final String txt)
{
try
{
Main.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
MyDialogFragment newFragment = MyDialogFragment.newInstance(txt);
FragmentTransaction ft = Main.this.getSupportFragmentManager().beginTransaction();
newFragment.show(ft, "newFragment");
}
});
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
MyDialogFragment.java :
public class MyDialogFragment extends DialogFragment
{
private MyDialogFragment instance;
public static MyDialogFragment newInstance(String text)
{
MyDialogFragment f = new MyDialogFragment();
Bundle args = new Bundle();
args.putString("text", text);
f.setArguments(args);
return f;
}
public MyDialogFragment()
{
instance = this;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.my_dialog_fragment, container, false);
TextView tv = (TextView) v.findViewById(R.id.tv);
Button bu = (Button) v.findViewById(R.id.bu);
bu.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
try
{
if(null != instance && instance.isVisible())
{
instance.dismiss();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
});
tv.setText(getArguments().getString("text"));
return v;
}
}
The answer is very simple, though a bit underwhelming.
The oft-seen java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState exception is actually thrown by the FragmentManager class. The reason why is explained very well in this post by Alex Lockwood.
DialogFragments are Fragments (and thus managed by FragmentManager). Therefore, showing dialogs in this way can provoke the exception. However, the implementation of AlertDialog is completely different: it doesn't use Fragments at all (indeed, it actually predates Fragments). Hence, no exceptions.
I'm stuck with communication between activity and fragment using interface. I have created activity with child fragment. I wanna do some stuff with continuous thread defined in activity and during that thread when I'm getting some result at that time I wanna trigger to child fragment to do something.
My Container Activity
public class MySpaceActivity extends BaseDrawerActivity {
private OnSetLastSeenListener mListner;
public static Thread mThread = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setHeaders(Const.MY_SPACE);
super.setSubmenus(Const.MY_SPACE,
Utils.getSubmenuList(Const.MY_SPACE, MySpaceActivity.this),
submenuBean);
// super.attachFragment(submenuBean);
}
#Override
public void setHeaderSubMenu(SubmenuBean subMenuBean) {
// txt_submenu.setText(subMenuBean.getSubmenu_name());
this.submenuBean = subMenuBean;
Log.print("::::: setHeaderSubMenu ::::");
super.attachFragment(submenuBean);
}
public void setsubFragment(SubmenuBean subMenuBean) {
this.submenuBean = subMenuBean;
super.attachSubFragment(submenuBean);
}
#Override
public void onBackPressed() {
super.onBackPressed();
popLastFragment();
}
private void popLastFragment() {
if (super.getNumberOfChilds() > 1) {
super.popSubFragment();
} else {
finish();
}
}
#Override
protected Fragment getFragement() {
StudentsFragment fragment = new StudentsFragment(Const.MY_SPACE,
getSubmenubean());
return fragment;
}
public SubmenuBean getSubmenubean() {
return submenuBean;
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
mThread = new Thread(new CountDownTimer(MySpaceActivity.this));
mThread.start();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
if (mThread.isAlive()) {
mThread.interrupt();
mThread = null;
}
}
public void updateLastSeen(){
Log.print("::::::Call Interface::::::");
mListner.updateLastSeen();
}
class CountDownTimer implements Runnable {
private Context mContext;
private JSONObject mJsonObject;
private JSONArray mJsonArray;
public CountDownTimer(Context mContext) {
this.mContext = mContext;
}
// #Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
HttpChatLastSeen mChat = new HttpChatLastSeen();
mJsonObject = mChat.Http_ChatLastSeen(mContext);
String mResult = mJsonObject.getString("Result");
if (mResult.equalsIgnoreCase(String
.valueOf(Const.RESULT_OK))) {
mJsonArray = mJsonObject.getJSONArray("UserData");
for (int i = 0; i < mJsonArray.length(); i++) {
mJsonObject = mJsonArray.getJSONObject(i);
new DbStudentMasterBll(mContext).update(
"last_seen", mJsonObject
.getString("LastSeen"), Integer
.parseInt(mJsonObject
.getString("UserId")));
}
} else {
Log.print("MY LAST SEEN Response : "
+ mJsonObject.toString());
}
updateLastSeen();
Thread.sleep(15000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (Exception e) {
Log.print("ChatLastSeenThread : ", e.getMessage());
}
}
}
}
}
My Child Fragment With Interface :
public class StudentsFragment extends Fragment implements OnSetLastSeenListener{
TextView txt_submenu;
ListView list_students;
SubmenuBean submenuBean;
int Mainmenu;
MySpaceActivity mMySpaceActivity;
ArrayList<DbStudentMasterBean> studentsList;
StudentsAdapter mAdapter = null;
OnSetLastSeenListener mListner;
public StudentsFragment() {
super();
}
public StudentsFragment(int Mainmenu, SubmenuBean submenuBean) {
this.submenuBean = submenuBean;
this.Mainmenu = Mainmenu;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_students, container,
false);
mMySpaceActivity = (MySpaceActivity) getActivity();
txt_submenu = (TextView) view.findViewById(R.id.txt_submenu);
txt_submenu.setText(submenuBean.getSubmenu_name());
txt_submenu.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mMySpaceActivity.openDrawer();
}
});
list_students = (ListView) view.findViewById(R.id.list_colleagues);
studentsList = new DbStudentMasterBll(getActivity()).getAllRecords();
mAdapter = new StudentsAdapter(getActivity(), studentsList, handler);
list_students.setAdapter(mAdapter);
list_students.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
DbStudentMasterBean bean = (DbStudentMasterBean) parent
.getAdapter().getItem(position);
Message msg = new Message();
msg.what = CHAT;
msg.obj = bean;
handler.sendMessage(msg);
}
});
return view;
}
Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case CHAT:
submenuBean.setTag(VIEWCHATSTUDENT);
DbStudentMasterBean bean = (DbStudentMasterBean) msg.obj;
mMySpaceActivity.setsubFragment(submenuBean);
break;
}
};
};
#Override
public void updateLastSeen() {
// TODO Auto-generated method stub
Log.print("!!!!!!!!!Refresh Adapter!!!!!!!!!!!");
mAdapter.notifyDataSetChanged();
}
}
My Interface :
public interface OnSetLastSeenListener {
public void updateLastSeen();
}
So I have implemented interface OnSetLastSeenListener with my child fragment StudentsFragment . Now I'm calling method of tht interface updateLastSeen() from my container activity with thread. But it is not getting trigger to child fragment where I have implemented interface. So I don't know whether it is good way to communicate or not? Let me take your help to suggest on this solution or best way to communicate from child fragment to parent activity.
Thanks,
It is better to use interface when you want to communicate something from Fragment to Activity and not vice versa.
In your case, you can directly call the method in Fragment from Activity through fragment object. No need to use interface.
Something like this (For static fragments)
StudentsFragment fragment = (StudentsFragment) getFragmentManager()
.findFragmentById(R.id.fragmentid);
if (fragment != null && fragment.isInLayout()) {
fragment.updateLastSeen();
}
For dynamic fragment you can use the fragment object directly.
I got a method in which server-client communication is done "onClick" therefor i create a anonymous OnClickListener, and I want to publish a toast if the communication was successfull or not.
To do this I need the Acitivity in which context to publish the toast, and as I externalized the method, it must be given as a "this" argument to the Activity. But as I am inside an anonymous inner class I cannot access the this pointer of the Acitivity, and even though I stored it in a local final variable
private final Activity activity = this;
#Override
public void onCreate(Bundle savedInstanceState) {
lastResult = null;
super.onCreate(savedInstanceState);
setLayout(R.layout.main);
qrscan = (Button) findViewById(R.id.qrcodescan);
qrscan.setOnClickListener( new View.OnClickListener() {
public void onClick(View view) {
initiateScan(activity);
}
}
);
}
private AlertDialog initiateSend(Activity activity) {
if(lastResult != null) {
String[] arr = lastResult.content.split("/");
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
String[] args = Util.filterString(arr,this);
downloadDialog.setTitle(args[0]);
downloadDialog.setMessage("Auftragsnummer:" + args[1]);
downloadDialog.setPositiveButton(getString(R.string.ja), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
try {
String send = lastResult.content;
send += "/uid/" + R.id.username + "/cid/" + R.id.password;
String result = Util.send(send);
//toaster(send);
Util.toaster(result,activity);
if(!(result.equals("OK") || result.equals("ok") || result.equals("Ok")))
throw new Exception("Bad Server Answer");
Util.toaster("Communication erfolgreich",activity);
} catch(Exception ex) {
ex.printStackTrace();
Util.toaster("Communication nicht erfolgreich",activity);
}
}
});
downloadDialog.setNegativeButton(getString(R.string.nein), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {}
});
return downloadDialog.show();
}
return null;
}
Any clue what i messed up?
declare variable before onCreate() like this
public class HelloAndroid extends Activity {
Activity activity = this; // declare here
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
EDITED
Activity mainActivity;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setLayout(R.layout.main);
mainActivity = this;
lastResult = null;
qrscan = (Button) findViewById(R.id.qrcodescan);
qrscan.setOnClickListener( new View.OnClickListener() {
public void onClick(View view) {
initiateScan(mainActivity);
}
}
);
}
private AlertDialog initiateSend(final Activity activity) {
if(lastResult != null) {
String[] arr = lastResult.content.split("/");
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
String[] args = Util.filterString(arr,this);
downloadDialog.setTitle(args[0]);
downloadDialog.setMessage("Auftragsnummer:" + args[1]);
downloadDialog.setPositiveButton(getString(R.string.ja), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
try {
String send = lastResult.content;
send += "/uid/" + R.id.username + "/cid/" + R.id.password;
String result = Util.send(send);
//toaster(send);
Util.toaster(result,activity);
if(!(result.equals("OK") || result.equals("ok") || result.equals("Ok")))
throw new Exception("Bad Server Answer");
Util.toaster("Communication erfolgreich",activity);
} catch(Exception ex) {
ex.printStackTrace();
Util.toaster("Communication nicht erfolgreich",activity);
}
}
});
downloadDialog.setNegativeButton(getString(R.string.nein), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {}
});
return downloadDialog.show();
}
return null;
}