I know that onBackPressed() is a method in activity but, I want to use the functionality in fragments such that when back button is pressed, it gets redirected to another activity via Intent. Is there any solution to this ?
public class News_Events_fragment extends Fragment {
ProgressDialog pd;
ListView lv1;
SharedPreferences sharedPreferences = null;
int NotiCount;
TextView txt_title, txt_msg, textView;
Context context;
Intent intent ;
ArrayList<SliderMsgTitleModel> CurrentOfficersPastList;
NewsActivityAdapter pastAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
context = (Context) getActivity();
View rootView = inflater.inflate(R.layout.activity_news, container, false);
new AsyncTask<Void, Void, ArrayList<SliderMsgTitleModel>>() {
protected void onPreExecute() {
pd = new ProgressDialog(getActivity());
pd.setCancelable(true);
pd.setTitle("UPOA");
pd.setMessage("Please wait,loading the data...");
pd.show();
}
#Override
protected ArrayList<SliderMsgTitleModel> doInBackground(
Void... params) {
System.out.println("In Background");
CurrentOfficersPastList = new ArrayList<SliderMsgTitleModel>();
// display view for selected nav drawer item
ParseQuery<ParseObject> query = ParseQuery.getQuery("message");
query.whereEqualTo("featured_status", true);
// query.whereEqualTo("push_status", true);
query.orderByDescending("updatedAt");
query.selectKeys(Arrays.asList("title"));
query.selectKeys(Arrays.asList("message"));
try {
query.setCachePolicy(ParseQuery.CachePolicy.NETWORK_ELSE_CACHE);
List<ParseObject> results = query.find();
for (int i = 0; i < results.size(); i++) {
ParseObject object = results.get(i);
CurrentOfficersPastList.add(new SliderMsgTitleModel(
object.getString("title"), object
.getString("message")));
System.out.println("title is=="
+ object.getString("title") + "&& message is"
+ object.getString("message") + "size is"
+ CurrentOfficersPastList.size());
}
} catch (Exception e) {
e.getMessage();
}
pd.dismiss();
return CurrentOfficersPastList;
}
#SuppressWarnings("unchecked")
#Override
protected void onPostExecute(ArrayList<SliderMsgTitleModel> value) {
pd.dismiss();
/*Intent ent = new Intent(getActivity(), NewsActivity.class);
ent.putExtra("NEWSLIST", (ArrayList<SliderMsgTitleModel>) value);
startActivity(ent);
System.out.println("Value is" + value.size());*/
CurrentOfficersPastList = new ArrayList<SliderMsgTitleModel>();
CurrentOfficersPastList = value;
lv1 = (ListView) getActivity().findViewById(R.id.list_title);
pastAdapter = new NewsActivityAdapter(getActivity(), R.layout.activity_news_txt, CurrentOfficersPastList);
lv1.setAdapter(pastAdapter);
}
}.execute();
return rootView;
}
public void onBackPressed() {
// TODO Auto-generated method stub
//super.onBackPressed();
//Toast.makeText(getApplicationContext(), "click",2000).show();
String cameback="CameBack";
intent = new Intent(getActivity(),HomeActivity.class);
intent.putExtra("Comingback", cameback);
startActivity(intent);
}
}
You can interact with the fragment using a callback interface. In your activity add the following:
public class MyActivity extends Activity {
protected OnBackPressedListener onBackPressedListener;
public interface OnBackPressedListener {
void doBack();
}
public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
this.onBackPressedListener = onBackPressedListener;
}
#Override
public void onBackPressed() {
if (onBackPressedListener != null)
onBackPressedListener.doBack();
else
super.onBackPressed();
}
#Override
protected void onDestroy() {
onBackPressedListener = null;
super.onDestroy();
}
}
In your fragment add the following:
public class MyFragment extends Fragment implements MyActivity.OnBackPressedListener {
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
((MyActivity) getActivity()).setOnBackPressedListener(this);
}
#Override
public void doBack() {
//BackPressed in activity will call this;
}
}
Yes, There is. You should implement like this.
#Override
public void onBackPressed() {
if (fragment != null)
//user defined onBackPressed method. Not of Fragment.
fragment.onBackPressed();
} else {
//this will pass BackPress event to activity. If not called, it will
//prevent activity to get BackPress event.
super.onBackPressed();
}
}
Explanation
Check whether your fragment is initialized or not. If it is, then pass on back press event to your fragment.
If above condition not passed, just pass back press to your activity so that it will handle it.
Note
Here condition can be anything. I just take fragment initialization as an example. May be that can't be helped you. You need to define your own condition to pass it to fragment.
Edit
I created a sample application on GitHub to implement Back Stack of fragment .
Download Fragment Back Stack application.
Override onKeyDown instead of onBackPressed. Not necessarily . But this works for me
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
String cameback="CameBack";
intent = new Intent(getActivity(),HomeActivity.class);
intent.putExtra("Comingback", cameback);
startActivity(intent);
return true
}
return false;
}
You can implement onKeyListener for your fragment and call next activity within that.
I've never tried this. But i hope it may help
For Example
fragmentObject.getView().setOnKeyListener( new OnKeyListener()
{
#Override
public boolean onKey( View v, int keyCode, KeyEvent event )
{
if( keyCode == KeyEvent.KEYCODE_BACK )
{
//your code here
}
return false;
}
} );
You need to override onBackPressed method in fragment.
Related
i'm using backbutton as interface from activity but it's not working properly for me because on backpress showing 0 size of arraylist
// here is the activity class from where i'm getting backbutton interface..
public class Multiple_Images extends AppCompatActivity {
#Override
public void onBackPressed() {
if(twice ==true){
Intent intent =new Intent(this,MainActivity.class);
startActivity(intent);
}ImageAdapter imageAdapter =new ImageAdapter(this);
imageAdapter.onBackPress();
Toast.makeText(this, "Press twice", Toast.LENGTH_SHORT).show();
twice =true;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
twice =false; } }, 2000); }}
//here is the adapter class here i'm using backbutton
public class ImageAdapter extends BaseAdapter implements onBackPressListener {
ArrayList<String> selectedArraylist ;
#Override
public boolean onBackPress() {
selectedArraylist.clear();
Toast.makeText(context, "All values unselected", Toast.LENGTH_SHORT).show();
return true;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
urimodel=new ArrayList<>();
final ImageView imageGrid ;
Activity activity = (Activity) context;
actionMode = activity.startActionMode(new Actionmode());
final GridModel gridModel=(GridModel) this.getItem(i);
if(view==null) {
view = LayoutInflater.from(context).inflate(R.layout.model, null);
selectedArraylist =new ArrayList<>();
}
final CardView cardView= (CardView)view.findViewById(R.id.cardview_image);
imageGrid = (ImageView) view.findViewById(R.id.grid_image);
// gridText = (TextView) view.findViewById(R.id.grid_text);
imageGrid.setScaleType(ImageView.ScaleType.CENTER_CROP);
// imageGrid.setScaleType(ImageView.ScaleType.CENTER_CROP);
Picasso.get().load(gridModel.getImage()).resize(200,200).into(imageGrid);
if (selectedArraylist.contains(gridModel.getImage_text())) {
cardView.setCardBackgroundColor(CARD_SELECTED_COLOR);
}else {
cardView.setCardBackgroundColor(Color.WHITE);
}
return view;
}
}
Simply you can do this inside onBackPressed
#Override
public void onBackPressed() {
if (twice == true) {
super.onBackPressed(); //this backs to the previous activity, if you want to stay with Intent, add finish() after startActivity()
return;
} else {
for (int i = 0; i < list.size(); i++) {
if (gridView.isItemChecked(i)) {
gridView.setItemChecked(i, false);
}
}
//selectedArraylist.clear(); this is clearing your array of selected items
}
twice = true;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
twice = false;
}
}, 2000);
}
I don't know, why did you put selectedArraylist =new ArrayList<>(); in adapter getView() method. getView() is fired every time, when a new list item is inflated, that mean every time, when you are changing adapters source, scrolling list this method is called, and every time you are initialize you array, and all data inside lost. You should treat an adapter class just like a tool for displaying items, and all actions like above make outside adapter.
pretty much easy,
I give you my own project code, hope it help you.
StudentFragment.java:
private void MultiSelected_Student(int position) {
Student data = adapter_class.getItem(position);
if (data != null) {
if (selectedIds.contains(data)) selectedIds.remove(data);
else selectedIds.add(data);
}
}
private void Remove_MultiSelected() {
try {
selectedIds.clear();
} catch (Exception e) {
e.printStackTrace();
}
}
public void Group_UnSelect() {
Remove_MultiSelected();
MultiSelected = false;
fab.setVisibility(View.GONE);
homeeActivity.studentsMultiSelect = false;
notifyy();
}
private void notifyy() {
adapter_class.notifyDataSetChanged();
}
HomeActivity.java:
public boolean studentsMultiSelect = false;
#Override
public void onBackPressed() {
if (studentsMultiSelect) {
studentFragment.Group_UnSelect();
} else {
super.onBackPressed();
}
}
I have a fragment inside of which I call an asynctask to get some data and then update some textviews.
The problem is that the whole procedure works well when I first visit this fragment. If I change to another fragment and then come back, the textviews are not updated through settext, although if I call gettext after the update, it returns the values that were supposed to be shown.
I initialize the textviews in fragment's onCreateView and update them in asynctask's onPostExecute.
I hope I explained it well.. Any ideas what could be the issue?
onCreateView:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_medical, container, false);
mContext = (FragmentActivity)getActivity();
current_meas_data = (TextView) v.findViewById(R.id.current_measurement_data);
bt = new MedicalBluetooth(mContext);
return v;
}
onStart:
public void onStart() {
super.onStart();
boolean btavailable = bt.isBluetoothAvailable();
if (btavailable == false) {
Toast.makeText(mContext, "Bluetooth is not available",
Toast.LENGTH_LONG).show();
return;
}
boolean btenabled = bt.isBluetoothEnabled();
if (btenabled) {
bt.setupService();
bt.startService();
} else {
Intent enableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, 1);
}
bt.setOnDataReceivedListener(new MedicalBluetooth.OnDataReceivedListener() {
public void onDataReceived(final byte[] data, String message) {
new GetMeasurementTask().execute(data);
}
});
}
AsyncTask:
private class GetMeasurementTask extends AsyncTask<byte[], Integer, Boolean> {
private ProgressDialog dialog = new ProgressDialog(mContext);
protected void onPreExecute() {
this.dialog.setMessage("Please wait");
this.dialog.show();
}
#Override
protected Boolean doInBackground(byte[]... params) {
com.example.bluetoothlibrary.Measurement mes = new com.example.bluetoothlibrary.Measurement();
mes = bt.manageData(params[0]);
return true;
}
protected void onPostExecute(Boolean result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (result == true) {
//Toast.makeText(mContext, "Call Successful!", Toast.LENGTH_LONG).show();
Log.d("BEFORE SETTEXT",current_meas_data.getText().toString());
current_meas_data.setText(mes.data);
Log.d("AFTER SETTEXT",current_meas_data.getText().toString());
}
if (result == false) {
//Toast.makeText(mContext, "Call Error", Toast.LENGTH_LONG).show();
}
}
}
The log says:
BEFORE SETTEXT:
AFTER SETTEXT: 20
but the "current_meas_data" is empty.
From what I understand is that you are probably calling your Async Task in onCreatView of your Fragment A. So if you go to Fragment B and press the back button, the onCreateView of Fragment A is not triggered as it is already in the stack. For this call your AsyncTask in onResume() in Fragment A. So override onResume in Fragment A and call the asyncTask.execute() method in that.
You definitely need to post some code.
EDIT: This question was created as part of one of my first Android projects when I was just starting out with Android application development. I'm keeping this for historical reasons, but you should consider using EventBus or RxJava instead. This is a gigantic mess.
Please DO NOT CONSIDER using this. Thank you.
In fact, if you want something cool that solves the problem of using a single activity with multiple "fragments", then use flowless with custom viewgroups.
I have implemented a way to initiate the creation of Fragments, from Fragments using a broadcast intent through the LocalBroadcastManager to tell the Activity what Fragment to instantiate.
I know this is a terribly long amount of code, but I'm not asking for debugging, it works perfectly as I intended - the data is received, the creation can be parametrized by Bundles, and Fragments don't directly instantiate other Fragments.
public abstract class FragmentCreator implements Parcelable
{
public static String fragmentCreatorKey = "fragmentCreator";
public static String fragmentCreationBroadcastMessage = "fragment-creation";
public static String fragmentDialogCreationBroadcastMessage = "fragment-dialog-creation";
protected Bundle arguments;
protected Boolean hasBundle;
public FragmentCreator(Bundle arguments, boolean hasBundle)
{
this.arguments = arguments;
this.hasBundle = hasBundle;
}
protected FragmentCreator(Parcel in)
{
hasBundle = (Boolean) in.readSerializable();
if (hasBundle == true && arguments == null)
{
arguments = in.readBundle();
}
}
public Fragment createFragment()
{
Fragment fragment = instantiateFragment();
if (arguments != null)
{
fragment.setArguments(arguments);
}
return fragment;
}
protected abstract Fragment instantiateFragment();
#Override
public int describeContents()
{
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeSerializable(hasBundle);
if (arguments != null)
{
arguments.writeToParcel(dest, 0);
}
}
public void sendFragmentCreationMessage(Context context)
{
Intent intent = new Intent(FragmentCreator.fragmentCreationBroadcastMessage);
intent.putExtra(FragmentCreator.fragmentCreatorKey, this);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
public void sendDialogFragmentCreationMessage(Context context)
{
Intent intent = new Intent(FragmentCreator.fragmentDialogCreationBroadcastMessage);
intent.putExtra(FragmentCreator.fragmentCreatorKey, this);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
}
This way, a Fragment that is created looks like this:
public class TemplateFragment extends Fragment implements GetActionBarTitle, View.OnClickListener
{
private int titleId;
public TemplateFragment()
{
titleId = R.string.app_name;
}
#Override
public int getActionBarTitleId()
{
return titleId;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_template, container, false);
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onClick(View v)
{
}
public static class Creator extends FragmentCreator
{
public Creator()
{
super(null, false);
}
public Creator(Bundle bundle)
{
super(bundle, true);
}
protected Creator(Parcel in)
{
super(in);
}
#Override
protected Fragment instantiateFragment()
{
return new TemplateFragment();
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<TemplateFragment.Creator> CREATOR = new Parcelable.Creator<TemplateFragment.Creator>()
{
#Override
public TemplateFragment.Creator createFromParcel(Parcel in)
{
return new TemplateFragment.Creator(in);
}
#Override
public TemplateFragment.Creator[] newArray(int size)
{
return new TemplateFragment.Creator[size];
}
};
}
}
The initial container activity that can process the messages looks like this:
Intent intent = new Intent();
intent.setClass(this.getActivity(), ContainerActivity.class);
intent.putExtra(FragmentCreator.fragmentCreatorKey,
new TemplateFragment.Creator());
startActivity(intent);
And the Fragments "instantiate other Fragments" like this:
Bundle bundle = new Bundle();
bundle.putParcelable("argument", data);
TemplateFragment.Creator creator = new TemplateFragment.Creator(bundle);
creator.sendFragmentCreationMessage(getActivity());
And the Container Activity receives the instantiation request:
public class ContainerActivity extends ActionBarActivity implements SetFragment, ShowDialog
{
private BroadcastReceiver mFragmentCreationMessageReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
setFragment((FragmentCreator) intent.getParcelableExtra(FragmentCreator.fragmentCreatorKey));
}
};
private BroadcastReceiver mFragmentDialogCreationMessageReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
showDialog((FragmentCreator) intent.getParcelableExtra(FragmentCreator.fragmentCreatorKey));
}
};
#Override
public void onCreate(Bundle saveInstanceState)
{
super.onCreate(saveInstanceState);
this.setContentView(R.layout.activity_container);
getActionBar().setDisplayHomeAsUpEnabled(true);
if (saveInstanceState == null)
{
Fragment fragment = ((FragmentCreator) getIntent().getParcelableExtra(
FragmentCreator.fragmentCreatorKey)).createFragment();
if (fragment != null)
{
replaceFragment(fragment);
}
}
else
{
this.getActionBar()
.setTitle(
((GetActionBarTitle) (this.getSupportFragmentManager()
.findFragmentById(R.id.activity_container_container)))
.getActionBarTitleId());
}
getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener()
{
public void onBackStackChanged()
{
int backCount = getSupportFragmentManager().getBackStackEntryCount();
if (backCount == 0)
{
finish();
}
}
});
}
#Override
protected void onResume()
{
LocalBroadcastManager.getInstance(this).registerReceiver(mFragmentCreationMessageReceiver,
new IntentFilter(FragmentCreator.fragmentCreationBroadcastMessage));
LocalBroadcastManager.getInstance(this).registerReceiver(mFragmentDialogCreationMessageReceiver,
new IntentFilter(FragmentCreator.fragmentDialogCreationBroadcastMessage));
super.onResume();
}
#Override
protected void onPause()
{
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mFragmentCreationMessageReceiver);
LocalBroadcastManager.getInstance(this).unregisterReceiver(
mFragmentDialogCreationMessageReceiver);
}
#Override
public void setFragment(FragmentCreator fragmentCreator)
{
Fragment fragment = fragmentCreator.createFragment();
replaceFragment(fragment);
}
public void replaceFragment(Fragment fragment)
{
if (fragment != null)
{
this.setTitle(((GetActionBarTitle) fragment).getActionBarTitleId());
getSupportFragmentManager().beginTransaction()
.replace(R.id.activity_container_container, fragment).addToBackStack(null).commit();
}
}
#Override
public void showDialog(FragmentCreator fragmentCreator)
{
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fragmentCreator.createFragment();
if (fragment instanceof DialogFragment)
{
DialogFragment df = (DialogFragment) fragment;
df.show(fm, "dialog");
}
else
{
Log.e(this.getClass().getSimpleName(), "showDialog() called with non-dialog parameter!");
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == android.R.id.home)
{
this.onBackPressed();
}
return super.onOptionsItemSelected(item);
}
}
My question is, is this actually a good idea, or is this a terrible case of "over-engineering" (creating a Factory for each Fragment and sending it to the Activity in the form of a local broadcast, rather than just casting the Activity of the most possible holder activity's interface and calling the function like that)?
My goal was that this way, I can use the same Activity for holding "branch" fragments, so that I don't need to make one for each menu point. Rather than just re-use the same activity, and divide all logic into fragments. (Currently it doesn't support orientation-based layout organization, I see that downside - and also that this way each Fragment needs to hold a static creator, which is extra 'boilerplate code').
If you know the answer why I shouldn't be using the local broadcast manager for this, I'll be happy to hear the response. I think it's pretty neat, but there's a chance it's just overcomplicating something simple.
You can use Interface for it so main objective of Fragment re-usability is maintained. You can implement communication between Activity-Fragment OR Fragment-Fragment via using following :
I am asuming that your moto is Fragment to communicate with its Activity and other Fragments.
If this is the case please go throught it.
To allow a Fragment to communicate up to its Activity, you can define an interface in the Fragment class and implement it within the Activity. The Fragment captures the interface implementation during its onAttach() lifecycle method and can then call the Interface methods in order to communicate with the Activity.
Example :
# In fragment
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mCallback = (OnHeadlineSelectedListener) activity;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
mCallback.onArticleSelected(position);
}
}
# In Activity
public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{
public void onArticleSelected(int position) {
// Do something here
}
}
Link: http://developer.android.com/training/basics/fragments/communicating.html
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.
In my application I have 2 fragment, Fragment A and Fragment B.On both these fragments Iam doing some XML parsing and populating listviews.I want to implement a splash screen for my app.So that it display during parsing and population of listviews and finishes when its done. For this, I have created an activity SplashActivity.I have Implemented asyntask on FragmentA and called the SplashActivity on preexecute section.Now, when the app launches SplashActivity get started.But I cant finish this acitivity on postexecute of FragmentA. getActivity().finishActivity() is not working.Please some one help me to solve this issue or suggest me another method to implement Splash screen on Fragment Activity. Thanks in advance....
here is my FragmentA=>
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflating layout
View v = inflater
.inflate(R.layout.headlines_fragment, container, false);
return v;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.i("Tag", "onCreateView");
// We set clear listener
loading = (ProgressBar) getActivity().findViewById(R.id.progressBar1);
if (Headlines.headflag == "malayalam") {
urls = "http://www.abc.com/rssfeeds/19_18_17_25/1/rss.xml";
}
if (Headlines.headflag == "english") {
urls = "http://www.abc.com/en/rssfeeds/1_2_3_5/latest/rss.xml";
}
new ProgressAsyncTask().execute();
MainActivity.refresh.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new ProgressAsyncTask().execute();
}
});
}
public void populate_listview() {
newsList = new ArrayList<HashMap<String, String>>();
// looping through all song nodes <song>
for (int i = 0; i < nl.getLength(); i++) {
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
newsList.add(map);
MarqueeStr = MarqueeStr + " *** " + Title[i];
}
}
public void StartProgress() {
new ProgressAsyncTask().execute();
}
public class ProgressAsyncTask extends AsyncTask<Void, Integer, Void> {
int myProgress;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
myProgress = 0;
Intent intent = new Intent(getActivity(), Splash.class);
startActivityForResult(intent, 5); //Here I called Splash Activity
loading.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
getActivity().finishActivity(5);// Here I tried to finish flash activity
if (Title == null) {
final AlertDialog.Builder alertbox = new AlertDialog.Builder(
getActivity());
alertbox.setMessage("Error in connection.Do you want to retry");
alertbox.setPositiveButton("retry",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
// getActivity().finish();
// Intent intent = new Intent(getActivity(),
// MainActivity.class);
// startActivityForResult(intent,1);
}
});
alertbox.setNegativeButton("exit",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
// getActivity().finish();
}
});
alertbox.show();
}
list = (GridView) getActivity().findViewById(R.id.grid);
// Getting adapter by passing xml data ArrayList
adapter = new HeadlinesAdapter(getActivity(), newsList);
list.setAdapter(adapter);
loading.setVisibility(View.INVISIBLE);
Typeface tf = Typeface.createFromAsset(getActivity().getAssets(),
"fonts/karthika.TTF");
MainActivity.flashnews.setText(MarqueeStr);
if (Headlines.headflag == "malayalam") {
MainActivity.flashnews.setTypeface(tf);
}
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent myintent = new Intent(
"com.abc.malayalam2headlinespodcast.PODCAST");
Bundle mybundle = new Bundle();
mybundle.putInt("number", position);
myintent.putExtras(mybundle);
startActivity(myintent);
}
});
}
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
parse();
if (Title != null) {
populate_listview();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
}
}
public static void parse() {
//parsing done here
}
}
You should not implement your Splash as an Activity but rather as a DialogFragment. Simply style that dialog fragment so that it appears fullscreen.
Concerning showing:
SplashDialogFragment splashDlg = new SplashDialogFragment();
splashDlg.show(getSupportFragmentManager(), "SplashScreen");
Then closing:
SplashDialogFragment splashDlg = (SplashDialogFragment) getSupportFragmentManager().findByTag("SplashScreen");
splashDlg.dismiss();
just to answer the question which is your title actually "To finish an activity from Fragment", it's always a good way to use interface to interact from Fragment to Activity as per the docs: Communicating with Activity from Fragment. So one must always declare an interface in Fragment which is to be implemented in your activity something like below:
public class SplashActivity extends Activity implements FragmentA.FragmentListenerCallback {
public void onFragmentInteraction() {
//finish your activity or do whatever you like
finish();
}
}
public class FragmentA extends Fragment {
private FragmentListenerCallback fragmentListenerCallback;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
fragmentListenerCallback = (FragmentListenerCallback) activity;
}
public interface FragmentListenerCallback {
void onFragmentInteraction();
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(fragmentListenerCallback != null){
fragmentListenerCallback.onFragmentInteraction();
}
}
}