Jai Jai - 2 months ago 7
Android Question

Call method of interface implements with child fragment From container activity Android

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,

Answer

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.