Start activity in a Fragment - java

I've decided to add more tablet-friendly UI to my app by creating a dual-pane layout using the new fragments API. But the problem is that lots of screens in my app are Activity subclasses. Manually converting them all to fragments is not an option because:
- There are nearly 50 activities.
- I'd like my app to be compatible with all versions of Android starting at 1.6
- And I'd like it to be as small as possible so using a compatibility library is not an option as it is too huge
Although I've found some questions whose answers are saying that it is impossible, I've done it almost successfully. Here is code of my custom Fragment:
public static class ActivityFragment extends Fragment{
Intent intent;
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(intent==null){
Bundle a=getArguments();
intent=a.getParcelable("intent");
}
LocalActivityManager am=((ActivityGroup)getActivity()).getLocalActivityManager();
Window wnd=am.startActivity("intent"+intent.hashCode(), intent);
if(view==null){
view=wnd.getDecorView();
view.setLayoutParams(new FrameLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
}
return view;
}
public void onDestroy(){
super.onDestroy();
if(!((TabletMainActivity)getActivity()).tabs.containsValue(this)){
((ActivityGroup)getActivity()).getLocalActivityManager().destroyActivity("intent"+intent.hashCode(), true);
}
}
}
In order to work it must be used only in ActivityGroup.
Only problem is that in some activities with a ListView method onItemClick() does not get called after the activity is resumed, i.e. I click an item, another activity starts on top of current, but when I go back, items are no longer clickable.

I've finally found a solution by comparing all ListView's fields' values before and after onResume. And solution to this problem is to call the notifyDataSetInvalidated() method on the list adapter.

Related

Putting a menu inside a Navmenu fragment java android

I'm developing a Java android app for my current school project. The app contains of a navigation menu with 3 sections.
One section contains a on swipe card view, second displays my jobs and the third one is account settings.
The second fragment my jobs is ment to be as follows:Form
The problem is how to set the top menu inside that certain fragment. My jobs should show one fragment containing "Jobs" that I am a part off, and the other menu option Jobs that I offer should show my listed jobs inside a recycler view and it should contain a button that opens the form to create a new job.
So far I filled up the fragment my jobs with the needed recycler view but I struggle with the menu itself.
problematic menu
Code for frag1:
public class MojiPosloviFragment extends Fragment {
RecyclerView recyclerPoslovi;
List<Posao> posloviD;
String nazivPoslodavca;
Intent intent;
public MojPosaoAdapter mojiPosloviAdapter;
private MojPosaoAdapter.MojPosaoClickListener listener;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_moji_poslovi, container, false);
Note: That mentioned fragment is a part of navmenu!

In android Studio, I want when i click on button , next activity/fragment should come from right side

In android Studio, I want when i click on button , next activity/fragment should come from right side and present activity sholud gone left.I implimented its working on Activity but not on adapters is showing error.
holder.questions.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(DoctorsProfile.this,Questions.class);
i.putExtra("DOCTOR_ID",doctor_id);
startActivity(i);
overridePendingTransition( R.anim.slide_in_right_up, R.anim.slide_out_right_up);
}
});
overridePendingTransition is working on Activity but not working on Adapters of Recyclerview and Listview, Please tell any other option. I want when i click on recyclerview item next Activity should navigate or come from right side by using overridePendingTransition.
Fragment fragment = Fragment.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.fragment_slide_left_enter,
R.anim.fragment_slide_left_exit, R.anim.fragment_slide_right_enter,
R.anim.fragment_slide_right_exit);
Utils.addFragmentToActivity(fragmentTransaction, Fragment, R.id
.content_frame);
This tip features how to change Android’s default animation when switching between Activities.
The code to change the animation between two Activities is very simple: just call the overridePendingTransition() from the current Activity, after starting a new Intent. This method is available from Android version 2.0 (API level 5), and it takes two parameters, that are used to define the enter and exit animations of your current Activity.
Here’s an example:
//Calls a new Activity
startActivity(new Intent(this, NewActivity.class));
//Set the transition -> method available from Android 2.0 and beyond
overridePendingTransition(R.anim.slide_in_right_up, R.anim.slide_out_right_up);
These two parameters are resource IDs for animations defined with XML files (one for each animation). These files have to be placed inside the app’s res/anim folder. Examples of these files can be found at the Android API demo, inside the anim folder.
for example code visit http://www.christianpeeters.com/android-tutorials/tutorial-activity-slide-animation/#more-483
Change like this code you must be passing activity as context in adapter
holder.questions.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(DoctorsProfile.this,Questions.class);
i.putExtra("DOCTOR_ID",doctor_id);
Activity activity = (Activity) context;
activity.startActivity(i);
activity.overridePendingTransition(R.anim.slide_in_right_up, R.anim.slide_out_right_up);
}
});
Note : Context is the Base Object of Activity
Update :
I have checked the accepted answer but hope you understand that it will be called everytime when your activity get launched and thats not supposed to be best practice. I am suggesting better approach if you want to follow the accepted answer .
Alternative :
Pass one parameter in bundle to new activity to make sure that transition coming from that specific adapter so double transation should not happen when you are coming rom any other activity also.
There is a easy way to do this. just put overridePendingTransition on your OnCreate method of next Activity/Fragment.So that when next Activity will come it will come according to your choice.Need not add overridePendingTransition on adapters.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ask_question);
overridePendingTransition( R.anim.slide_in_right_up, R.anim.slide_out_right_up);
}

Can't use SharedPreference variables

I'm trying to save and retrieve data with SharedPreferences. Data stores and retrieved correctly, the problem is the app crashes on using this data to change a button text in a fragment
onCreateView() Function
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
SharedPreferences loadSettings = getActivity().getSharedPreferences("app_setts", Context.MODE_PRIVATE);
Button counterBtn = (Button) getActivity().findViewById(R.id.counterBtn);
int countInt = loadSettings.getInt("counter",0);
counterBtn.setText(String.valueOf(countInt));
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
So how to change the switch values using SharedPreference
*I have searched here but all gives crash
Sorry for bad english
Edit
I have found that i couldn't access the fragment component directly by onCreate() in MainActivity.java so i have to put my code in onCreateView() function
But there is a problem
The app runs and didn't crash but the value still won't change
Any idea to solve this ??
There's a couple of issues here.
The first is that you should probably move the code from your fragment's onCreateView() to onActivityCreated(), as that's when you are guaranteed that the Activity's onCreate has completed.
The second issue is that while this may work, it's poor design to have a fragment reach into and manipulate it's parent activity directly in this way.
The Android developer site has a good article about how to communicate between a fragment and it's activity via interfaces, at http://developer.android.com/training/basics/fragments/communicating.html
Personally, I prefer to decouple things even more, forego the interface, and use a message bus (e.g. Otto, EventBus, etc.) In this way, fragments are completely reusable / replaceable, and neither the activity nor the fragment need to know anything specific about each other - just which bus messages they emit / consume.
Logcat trace shows the 62nd line throws a NPE.
boolean onoffSwitch = loadSettings.getBoolean("appOnOff", false);
So, loadSettings must be null. You can print this by:
System.out.print(loadSettings);
So, you must try:
SharedPreferences loadSettings = getSharedPreferences("pref", Context.MODE_PRIVATE);
...
loadSettings.commit();
You may be try to get the shared preference value before save. First check you saving the values in shared preference..

How to get information from my Android Fragment to MyActivity.java

I'm trying to learn to create an Android fragment to implement an amount insert box which I can reuse throughout my application. So I create a simple xml file which has some EditText boxes. I then created the associated java file called AmountFragment.java:
public class AmountFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.amount_fragment, container, false);
return view;
}
}
I then use this fragment in another xml file:
<fragment
android:name="com.example.android.ui.widget.AmountFragment"
android:id="#+id/transaction_amount"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
This works fine so far. It shows the fragment fine and I can insert numbers in it. I now want to be able to get the inserted text in the mainActivity. So I read this page on Fragments from the Android docs, but I'm totally lost. The code they show makes no sense at all to me. I need to define an interface, but I have no clue what I have to do with it. I tried simply copy-pasting it over, but I get an InflateException. Since I don't even know what's going on I have no clue where to look for a solution.
So my question: can anybody give me some pointers on how to interface this fragment with the Activity in which I use it?
Try the following code.
In MainActivity.java add
public void getMessage(Object obj) {
Log.d("My App", "Look at my object " + obj.toString();
}
That will get objects from your AmountFragment, then in your AmountFragment write:
String anyObject = "Yay something";
((MainActivity)getActivity()).getMessage(anyObject);
What's happening here is that getActivity() will get the instance of the Activity which contains the fragment, then you cast it to your activity, MainActivity, and call the receiver method you wrote for it.

Android: Best way to retain listview content in fragment in tabbed app?

Firstly, this is my first question on StackOverflow so please forgive any formatting issues etc.
I'm writing an Android tablet application which allows users to populate a ListView with content pulled from a web service. At the minute there is one activity which contains a ViewPager which contains 6 fragments on different pages.
The issue is that the data which is downloaded and added to the ListView disappears when the user changes to another tab/back again and the Fragment's OnCreateView method is called (which initialises the ListView back to empty)
What's the best way of keeping the content of the listview besides storing it in a database/sharedprefs. The data in the listview needs to be destroyed when the user logs out/restarts the application, so I'm hoping to not persist it in any way.
the OnCreateView of the ListView container fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_certificate_list, container, false);
return rootView;
}
And here's the code which populates the ListView when the user hits the download button:
ListView lv = (ListView) callerActivity.findViewById(R.id.listView1);
lv.setAdapter(new CertListAdapter(callerActivity.getBaseContext(), activeCerts));
if (activeCerts.size() > 0) {
((TextView) callerActivity.findViewById(R.id.certStatusLabel)).setVisibility(View.GONE);
} else {
((TextView) callerActivity.findViewById(R.id.certStatusLabel)).setText(callerActivity.getString(R.string.certsDontExist));
}
the activeCerts variable is an arraylist of certificate objects which are obtained from the web service.
EDIT
Found a solution for this, to simply check if the "activeCerts" variable is null in the onCreateView method and populate the ListView again if it's not null. When the user logs out I'll just set activeCerts to null.
Cheers
"Correct" way:
use Fragment.onSaveInstanceState(Bundle) and Fragment.onActivityCreated(Bundle) to save and restore your items
Cheap way:
set android:configChanges="orientation|keyboardHidden|screenSize" on your activity hosting the fragment
You can also setRetainInstance(true); in the onCreate() of your Fragment
Read more about all this here.

Categories