I have an activity LoginActivity and a fragment GoogleSignInFragment. The login logic for the app works perfectly okay but the only thing bugging me is the fact that the GoogleSignInFragment didn't show up in the XML preview for activity_login.xml. Without it showing up, it'll be very difficult for me to move my code to Fragments, since I can't style the activity as well anymore
Here's all the relevant code...
LoginActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.sign_in_google, new GoogleSignInFragment())
.commit();
}
activity_login.xml
<FrameLayout
android:id="#+id/sign_in_google"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout="#layout/fragment_sign_in_google_button"/>
GoogleSignInFragment.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_google_sign_in_button, container, false);
return v;
}
fragment_google_sign_in_button.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
tools:context=".GoogleSignInFragment">
<com.google.android.gms.common.SignInButton
android:id="#+id/sign_in_google_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
</FrameLayout>
Sometimes Android Studio fails to load preview so you can try Invalidate Cache / Restart option in File option.
For this, Go to File > Click on Invalidate Cache / Restart
https://developer.android.com/studio/write/tool-attributes#toolslayout
Says it's meant for intended for: <fragment> but you are using a FrameLayout
I think they're no problem with your code ad your fragment activity_login.xml does not contain anything and fragment_google_sign_in_button.xml contains com.google.android.gms.common.SignInButton is used with help of an external library so sometimes preview not shows.
Related
I have a fragment (fragment_1) which gets displayed when the main activity starts and displays a full screen layout (layout_1). Now i have added a button, clicking on which will start a new fragment (fragment_2)and replace the entire layout (layout_1) with my new layout (layout_2).
My first fragment (fragment_1) has a ScrollView as my root view.
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:background="#fff"
android:scrollbarSize="0dp"
android:id="#+id/scroll_main"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
....
</RelativeLayout>
</ScrollView>
Now i want to start a new fragment (fragment_2) on a button click and display another layout (layout_2) but i don't know how to do that.
My main activity had a frame layout like this
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/root_container">
And i used to set this as my default layout using
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
After this i start my first fragment and display the layout_1.
Now from fragment_1 i want to start fragment_2 and display the layout_2. I have read online articles and documentation where i can't find and solution regarding this. Pleas Note :" I don't want to simply replace a part of my layout_1 and replace it with my layout_2 rather i want my layout_1 totally gets replaced with layout_2 on a button click"
Replacing fragments seems like a job for the fragment manager.
This answer might help you Replacing a fragment with another fragment inside activity group
This seems to be such a fundamental question that I'm embarrassed to ask it, but I'm so frustrated by my Fragment learning curve that I'll expose my ignorance.
An example in a textbook that cuts a lot of corners that make expanding them difficult, if they even work, had no button to click; MainActivity simply loaded FragmentA. OK, keep it basic. I get that.
So I added a button to MainActivity to click to load FragmentA, but the button shows on the FragmentA screen, sort of like this (not an actual screen shot, but close):
How do I prevent that? Should I use a second Activity instead of a Fragment? Since this endeavor is to be utilized in a much larger project, I don't want to do anything considered not best practice. I realize that the main use of Fragment is to enable side-by-side "screens" on devices that are large enough. That's not what I want to do, but it IS possible to accomplish what I want with a Fragment, isn't it?
MainActivity.java
public class MainActivity extends Activity {
#Override protected void onCreate(Bundle savedInstanceState)
{
super.onCreate( savedInstanceState);
setContentView(R.layout.activity_main);
}
public void btnLoadFragmentAByClick(View view)
{
FragmentA fragmentA;
fragmentA = new FragmentA();
FragmentTransaction ft ;
ft = getFragmentManager().beginTransaction();
ft.replace(R.id.layout_container, fragmentA);
ft.addToBackStack("example");
ft.commit();
}
}
FragmentA.java
public class FragmentA extends Fragment
{
#Override
public View onCreateView(LayoutInflater _inflater,
ViewGroup _container,
Bundle _savedInstanceState)
{
return _inflater.inflate(R.layout.fragment_a,
_container,
false);
}
}
activity_main.xml
<RelativeLayout
xmlns:android ="http://schemas.android.com/apk/res/android"
xmlns:tools ="http://schemas.android.com/tools"
android:layout_width ="match_parent"
android:layout_height ="match_parent"
tools:context =".MainActivity" >
<LinearLayout
android:id ="#+id/layout_container"
android:orientation ="vertical"
android:layout_width ="wrap_content"
android:layout_height="wrap_content"
>
</LinearLayout>
<Button
android:id ="#+id/btnLoadFragmentA"
android:text ="Load Fragment A"
android:onClick="btnLoadFragmentAByClick"
android:layout_width ="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
fragment_a.xml
<RelativeLayout
xmlns:android ="http://schemas.android.com/apk/res/android"
android:layout_width ="match_parent"
android:layout_height ="match_parent" >
<TextView
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
android:text ="Layout for fragment A"
android:textAppearance ="?android:attr/textAppearanceLarge"
>
</TextView>
</RelativeLayout>
EDIT
I realize that I could hide the MainActiviy button (and any other objects) before loading FragmentA and show them after returning, but I was hoping for a one-or-two-line "fix".
How do I prevent that?
Well, to some extent, you don't, insofar as this has nothing to do with fragments.
Your activity_main.xml has the Button floating over top of the LinearLayout (???) that you are using for your fragment container. If you do not want the Button floating over top of the fragment container, then fix the layout file to not have the Button floating over top of the fragment container.
I realize that I could hide the MainActiviy button (and any other objects) before loading FragmentA and show them after returning, but I was hoping for a one-or-two-line "fix".
The typical solution for full-UI replacement using fragments is to have everything in fragments. Your replace() would replace your original fragment with a replacement. So, in this case, your Button would be managed by one fragment, and clicking the Button would replace() that fragment with another fragment. Given that your FragmentTransaction has addToBackStack(), pressing BACK would get rid of the replacement fragment and return you to your Button fragment.
Disclaimer: It's build with CLI only tools, so certainly some "auto-generated lines" are missing
It's a small application with a MainActivity with a EditText and a Button
It works fine, but if I extends now from ActionBarActivity now my EditText and Button are hidden behind the Action Bar
https://developer.android.com/guide/topics/ui/actionbar.html The android documentation does not state about changes needing to be made in the layout.xml nor does the Training guide from which my application is based on
My MainActivity.java
public class MainActivity extends ActionBarActivity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// adding these lines show that the widget are correctly added
//ActionBar actionBar = getSupportActionBar();
//actionBar.hide();
}
}
My main layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText
android:id="#+id/enter_verb"
android:hint="#string/enter_verb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:text="#string/button_conjugate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
My guess would be that I need to add something in my layout to make it aware there's a Action Bar, but I can't find anywhere what it should be.
Very strange, I've added the line coming from this link
https://developer.android.com/training/basics/actionbar/overlaying.html
Which is:
android:paddingTop="?attr/actionBarSize"
in my LinearLayout tag, and then recompiled, after that the widget were shown but with a padding of the size of the actionBar in addition to the actionBar itself.
I then removed the line, recompiled and it now works as expected
A bug because of temporary files?
The SwipeRefreshLayout was added to the Android Support Library in v19.1.0:
https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html
I have now added it to my application and it works as advertised. However, if I swipe slowly, I notice the overscroll is very jerky. See this video to see what I mean:
https://www.youtube.com/watch?v=HAuadMZYRf0
I see the issue using multiple layouts of varying levels of complexity. The layout shown in the video linked above is:
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_refresh_widget"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
And the relevant Java code:
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
final Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.list, container, false);
mSwipeRefreshWidget = (SwipeRefreshLayout) v.findViewById(R.id.swipe_refresh_widget);
mSwipeRefreshWidget.setOnRefreshListener(this);
mSwipeRefreshWidget.setColorScheme(R.color.refresh1, R.color.refresh2, R.color.refresh3,
R.color.refresh4);
// snip
}
Full source on Github:
https://github.com/meisteg/PickTheWinner/blob/d764c69af0c72a2d1173c6fb4328bd85088d8b59/app/src/com/meiste/greg/ptw/tab/Schedule.java
Anyone have suggestions how to fix the jerkiness? The overscroll should be smooth, no matter how long I take to overscroll the required distance. Thanks!
This is fixed in the 20.0 version of the support-library v4.
If you are using gradle :
compile 'com.android.support:support-v4:20.0'
at the moment I'm calling and building fragments like this:
if (getSupportFragmentManager().findFragmentById(R.id.fragment_list) == null) {
list = new MyListFragment();
getSupportFragmentManager().beginTransaction().add(R.id.fragment_list, list).commit();
}
But I wonder if this is so called best practice, because this seems to me to be much boilerplate code. Are there better ways?
Use XML layouts and Fragment classes. Here I create a layout with 2 fragments. The class inflates the layout fragment_actionbarcompat.xml (that code isn't shown here but it's a basic layout file). And I create a layout file for the activity that houses the 2 fragments.
The ActionBarCompatFragment class overrides the onCreateView method to inflate it's layout. That gets injected into the fragment tag layoutwise.
In your case normally you don't just add in a plain ListFragment, you extend ListFragment and add your custom code into it. It's a way of better supporting fancy patterns like Model-View-Controller. Fragments are meant to be isolated compartments so you can reuse them between activities if you'd like. In most cases your class will hold the logic to load the data that the fragment needs.
ActionBarCompatFragment.java
#Override
public final View onCreateView(LayoutInflater inflater, ViewGroup root, Bundle savedInstanceState) {
final int layoutId = R.layout.fragment_actionbarcompat;
return inflater.inflate(layoutId, root, false);
}
File: activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="#+id/ActionBarCompatFragment"
android:layout_width="#dimen/ActionBarSize"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
class="com.packagename.app.ActionBarCompatFragment" >
<!-- Preview: layout=#layout/fragment_actionbarcompat -->
</fragment>
<fragment
android:id="#+id/ComposerFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="#id/ActionBarCompatFragment"
class="com.packagename.app.ComposerFragment" >
<!-- Preview: layout=#layout/fragment_composer -->
</fragment>
</RelativeLayout>