Redraw fragment after screen rotation with different layout - java

I am implementing the registration/login part of an application and I am trying to implement it in one activity by using different fragments for login and signup.
I have two different layouts for portrait and landscape mode, which are basically a vertical layout for the portrait one and a horizontal layout for landscape, both with a logo and a FrameLayout containing the fragment (let's consider ony the login one).
The fragment is inflated by an xml resource file and inserted programmatically in the activity onCreate() method in this way:
fragmentManager = this.getFragmentManager();
ViewGroup root = (ViewGroup) getWindow().getDecorView().findViewById(android.R.id.content);
LinearLayout linearLayout = (LinearLayout) root.getChildAt(0);
frameLayout = (FrameLayout) linearLayout.getChildAt(1);
loginFragment = (LoginFragment) fragmentManager.findFragmentByTag("loginFragment");
if (loginFragment == null) {
// If fragment wasn't saved, create new one
Log.d("DEBUG", "Fragment is null");
loginFragment = new LoginFragment();
}
else
Log.d("DEBUG", "Fragment is not null");
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(frameLayout.getId(), loginFragment, "loginFragment");
transaction.commit();
Everything works fine until I rotate the screen, then I get the following:
java.lang.IllegalStateException: Can't change container ID of fragment
LoginFragment{19d136ec #0 id=0x7f090040 loginFragment}: was 2131296320
now 2131296322
I tried to place fragmentManager.executePendingTransactions(); after the commits, but still the same problem. I really don't know what more to try, hope to get some hints.
EDIT: Here are the layout files
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView"
android:layout_gravity="center_horizontal"
android:src="#drawable/jobsharklogo"
android:layout_weight="1" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/frameLayout"
android:layout_weight="1" />
</LinearLayout>
and
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView2"
android:layout_gravity="center_vertical"
android:src="#drawable/jobsharklogo" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/frameLayout2"
android:layout_weight="1" />
</LinearLayout>
And LoginFragment code:
public class LoginFragment extends Fragment implements View.OnClickListener {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnLoginFragmentInteractionListener mListener;
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment LoginFragment.
*/
// TODO: Rename and change types and number of parameters
public static LoginFragment newInstance(String param1, String param2) {
LoginFragment fragment = new LoginFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public LoginFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_login, container, false);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1);
params.gravity = Gravity.CENTER;
view.setLayoutParams(params);
Button loginButton = (Button) view.findViewById(R.id.loginButton);
Button signupButton = (Button) view.findViewById(R.id.signupButton);
loginButton.setOnClickListener(this);
signupButton.setOnClickListener(this);
return view;
}
public void onClick(View button) {
if (mListener != null) {
mListener.onLoginFragmentInteraction(button.getId());
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnLoginFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnLoginFragmentInteractionListener {
public void onLoginFragmentInteraction(int id);
}
}

The trouble is probably that you're trying to replace a fragment you added via XML.
See: IllegalStateException when replacing a Fragment for the discussion.
Edit 2:
I use landscape mode also, and am able to rotate this and change layout.
Ok, I implemented your code (with what I could figure out from your code). I only changed the way I located the elements by using findViewBy().
In the activity:
public class LoginActivity extends Activity implements LoginFragment.OnLoginFragmentInteractionListener {
private FragmentManager fragmentManager;
private FrameLayout frameLayout;
private LoginFragment loginFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
fragmentManager = this.getFragmentManager();
ViewGroup root = (ViewGroup) getWindow().getDecorView().findViewById(android.R.id.content);
frameLayout = (FrameLayout) root.findViewById(R.id.frameLayout);
loginFragment = (LoginFragment) fragmentManager.findFragmentByTag("loginFragment");
if (loginFragment == null) {
// If fragment wasn't saved, create new one
Log.d("DEBUG", "Fragment is null");
loginFragment = new LoginFragment().newInstance("param1", "param2");
}
else
Log.d("DEBUG", "Fragment is not null");
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(frameLayout.getId(), loginFragment, "loginFragment");
transaction.commit();
}
#Override
public void onLoginFragmentInteraction(int id) {
Log.e("DEBuG", "id: "+id);
}
}
where main.xml is:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:background="#f0498a">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/frameLayout"
android:layout_weight="1" />
Clicking on the buttons in any of the rotation modes, I got:
E/DEBuG﹕ id: 2131296322
E/DEBuG﹕ id: 2131296321
The xml I used for landscape mode (put in layout-land
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:background="#color/material_blue_grey_900">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/frameLayout"
android:layout_weight="1" />
<Button
android:id="#+id/loginButton"
android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="login"/>
<Button
android:id="#+id/signupButton"
android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="sing in"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView2"
android:layout_gravity="center_vertical"
android:src="#drawable/jobsharklogo" />
and portrait mode (just in layout folder)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:background="#f0498a">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/frameLayout"
android:layout_weight="1" />
<Button
android:id="#+id/loginButton"
android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="login"/>
<Button
android:id="#+id/signupButton"
android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="sing in"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView"
android:layout_gravity="center_horizontal"
android:src="#drawable/jobsharklogo"
android:layout_weight="1" />

Related

Make the layout below button

In one of my fragment class, it has two buttons (A and B) on top, used to switch to another fragment when clicked using viewPager.
When buttonA is clicked, it should switch to page A and so on.
When I click button A, how can I make the text in A show below the two buttons?
fragment_menu.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">
<Button
android:id="#+id/buttonA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:padding="15dp"
android:text="ButtonA"
android:textSize="12sp" />
<Button
android:id="#+id/buttonB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:layout_marginRight="15dp"
android:layout_toRightOf="#+id/buttonB"
android:backgroundTint="#color/materialGrey600"
android:padding="15dp"
android:text="ButtonB"
android:textSize="12sp" />
<androidx.viewpager.widget.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
MenuFragment
public class MenuFragment extends BaseFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_menu, container, false);
final ViewPager viewPager = (ViewPager) v.findViewById(R.id.pager);
viewPager.setAdapter(new ViewPagerAdapter(getActivity().getFragmentManager()));
Button btnA = (Button) v.findViewById(R.id.buttonA);
Button btnB = (Button) v.findViewById(R.id.buttonB);
btnA.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
viewPager.setCurrentItem(0, true);
}
});
btnB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
viewPager.setCurrentItem(1, true);
}
});
return v;
}
}
ViewPagerAdapter
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position)
{
case 0:
return new A()
case 1:
return new B()
}
return null;
}
#Override
public int getCount() {
return 2;
}
}
Output
try with below code.hope it is helpful for you ;)
P.S. You just need to set button style as you want :)
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager.widget.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_above="#id/llButton"
android:layout_height="match_parent" />
<LinearLayout
android:id="#+id/llButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp">
<Button
android:id="#+id/buttonA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:padding="15dp"
android:text="ButtonA"
android:textSize="12sp" />
<Button
android:id="#+id/buttonB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:layout_marginRight="15dp"
android:backgroundTint="#color/colorAccent"
android:padding="15dp"
android:text="ButtonB"
android:textSize="12sp" />
</LinearLayout>
</RelativeLayout>
Since you are using Relative Layout you can add layout_below
<androidx.viewpager.widget.ViewPager
android:layout_below="#id/buttonB"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
you are doing it wrong, You cannot align a button to itself. That's why your buttons are not working properly. In your button B do this:
android:layout_toRightOf="#+id/buttonA"
instead of this:
android:layout_toRightOf="#+id/buttonB"
And to your viewPager add "android:layout_below:"
<androidx.viewpager.widget.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/buttonA" />
You have to set your layout like this....
[I think you want something like this 2 button fisrt and then viewpager for change the content ][1]
[1]: https://i.stack.imgur.com/dluXA.png
**Code for main Page **
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:orientation="vertical"
android:padding="5dp"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:padding="10dp"
android:layout_marginTop="10dp"
android:layout_height="match_parent"
android:orientation="horizontal">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/frame_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center_horizontal">
<Button
android:id="#+id/btn_donner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:background="#drawable/rect_outline"
android:text="Donor's"
android:textAlignment="center"
android:textColor="#color/white" />
<Button
android:id="#+id/btn_blood_bank"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Blood Bank"
android:background="#drawable/rect_outline"
android:layout_weight="2"
android:textAlignment="gravity"
android:textColor="#color/white" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</LinearLayout>
Code For Java File of two Buttons And ViewPager
//Click Event for donor's and blood bank .....
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View view) {
Fragment fragment = null;
if (view == view.findViewById(R.id.btn_donner))
{
fragment = new TabDonnerFragment();
}
else
{
fragment = new TabBloodBankFragment();
}
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.frame_content, fragment);
transaction.commit();
}
};
btn_donner.setOnClickListener(listener);
btn_blood_bank.setOnClickListener(listener);
return root;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Fragment fragment = null;
fragment = new TabDonnerFragment();
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.frame_content, fragment);
transaction.commit();
}
}

Activity is hidden by fragment, it is not useable

i have builded an app that works perfectly on android with api higer than 21. The problem is that this instruction of my code:
mFragmentTransaction.replace(R.id.content_frame, new TabFragment()).commit();
Works in different way on API less then 21.
On Api less then 21 the new fragment hide the previus activity, so that i can't click on my Floating Action Button.
Here are two images that explain in abetter way my problem.
API HIGER THAN 21
API LESS THAN 21
So my question is: How can i have the same result in API less then 21 that i have on API Higer then 21?
Here is the affected part of the Main Activity Code:
public class MainActivity extends AppCompatActivity {
public static AppDataBase appDataBase;
public static UserDataBase userDataBase;
static FragmentManager mFragmentManager;
static FragmentTransaction mFragmentTransaction;
private DrawerLayout myDrawerLayout;
final String TXT_MAINACTVT_USER_HAVE_NOT_ADDED_CONSOLE = "Add a console!";
TextView currentConsole;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
appDataBase = new AppDataBase(this);
userDataBase = new UserDataBase(this);
myDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
currentConsole = (TextView) findViewById(R.id.txt_Mainactvt_currentConsole);
currentConsole.setText(TXT_MAINACTVT_USER_HAVE_NOT_ADDED_CONSOLE);
tabLayoutManagement();
floatingActionButtonManagement();
leftDrawerMenuManagement();
rigthDrawerMenuManagement();
populateMyConsole();
}
void tabLayoutManagement() {
mFragmentManager = getSupportFragmentManager();
mFragmentTransaction = mFragmentManager.beginTransaction();
mFragmentTransaction.replace(R.id.content_frame, new TabFragment()).commit();
}
// Floating Action Button
private void floatingActionButtonManagement() {
FloatingActionButton fab_addGame = (FloatingActionButton)findViewById(R.id.fab_AddGame);
fab_addGame.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*
The currentConsole TextView is used to show at the user wich console is selected.
We use it to have a strng that conteins the selected console.
Call the method that manage the click event of the FloatingActionButton. We pass the console name.
*/
String currentConsoleName = currentConsole.getText().toString();
floatingActionButtonClickEvent(currentConsoleName);
}
});
}
private void floatingActionButtonClickEvent(String currentConsoleName) {
/*
Check if user have added a console. If he did start a menu for adding games, else start an
error message
*/
if (!currentConsoleName.equals(TXT_MAINACTVT_USER_HAVE_NOT_ADDED_CONSOLE)) {
popUpViewAddGameBuild(currentConsoleName);
}
else
mySimpleAlertDialogMethod("Attention!", "Before you enter game, you must enter a console.", true, true);
}
private void popUpViewAddGameBuild(String currentConsoleName) {
/*
Build the view that show the menu for adding games.
*/
LayoutInflater inflater = this.getLayoutInflater();
View popupView = inflater.inflate(R.layout.popupview_addgame, null);
PopupWindow popupWindow = new PopupWindow(
popupView,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT);
popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
popupWindow.setFocusable(true);
popupWindow.showAtLocation(popupView, 0, 0, 0);
}
Here is the TabLayout Class:
public class TabFragment extends Fragment {
public static TabLayout tabLayout;
public static ViewPager viewPager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View x = inflater.inflate(R.layout.tab_layout, null);
tabLayout = (TabLayout) x.findViewById(R.id.tabs);
viewPager = (ViewPager) x.findViewById(R.id.viewpager);
viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return x;
}
public class MyAdapter extends FragmentPagerAdapter {
public int position;
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0 :
return new DesireFragment();
case 1 :
return new BuyedFragment();
case 2 :
return new StartedFragment();
case 3 :
return new FinishedFragment();
case 4 :
return new AllTrophiesFragment();
}
return null;
}
#Override
public int getCount() {
return 5;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0 :
return "Desire";
case 1 :
return "Buyed";
case 2 :
return "Started";
case 3 :
return "Finished";
case 4 :
return "AllTrophies";
}
return null;
}
}
}
There is the layout of the MainActivity:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:layout_gravity="end"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:id="#+id/toolbar"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:navigationIcon="#drawable/ic_menu_white_24dp"
app:title="MyGames">
<Button
android:id="#+id/btnOpenRigthDrawer"
android:background="#drawable/ic_filter_list_white_24dp"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="10dp"
android:layout_gravity="right" />
<Button
android:id="#+id/btnOpenOptions"
android:background="#drawable/ic_settings_white_24dp"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="17dp"
android:layout_gravity="right" />
</android.support.v7.widget.Toolbar>
</RelativeLayout>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollIndicators="bottom">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:backgroundTint="#color/colorPrimary"
app:borderWidth="0dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/txt_Mainactvt_currentConsole"
android:layout_gravity="center_horizontal|top"
android:layout_marginTop="50dp"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab_AddGame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="17dp"
android:layout_marginRight="17dp"
android:src="#drawable/ic_mode_edit_white_24dp"
android:layout_gravity="bottom|right"
android:background="#color/colorPrimary" />
</FrameLayout>
<include
layout="#layout/drawer_left"
android:id="#+id/layLeft"
android:layout_gravity="start"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
<include
layout="#layout/drawer_rigth"
android:id="#+id/layRigth"
android:layout_gravity="end"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:scrollbars="vertical"
/>
</android.support.v4.widget.DrawerLayout>
And here is the layout code of the TabLayout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
app:tabGravity="fill"
app:tabMode="scrollable"
android:background="#color/colorPrimary"
app:tabIndicatorColor="#android:color/holo_orange_dark"
app:tabSelectedTextColor="#android:color/holo_orange_dark"
app:tabTextColor="#android:color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
You replace the content of your FrameLayout with an Fragment. this leads to your strange result.
Add a Layout to your Framelayout instead and use it as your FragmentContainer:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:backgroundTint="#color/colorPrimary"
app:borderWidth="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/content_frame"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/txt_Mainactvt_currentConsole"
android:layout_gravity="center_horizontal|top"
android:layout_marginTop="50dp"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab_AddGame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="17dp"
android:layout_marginRight="17dp"
android:src="#drawable/ic_mode_edit_white_24dp"
android:layout_gravity="bottom|right"
android:background="#color/colorPrimary" />
</FrameLayout>
Try to place your FrameLayout with this button to the end of layout

How to solve fragment overlap?

In fragment A, it has listView. When the list is clicked, it should pass the data to fragment B.
A.java
B fragment2 = new B();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment1, fragment2);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
B.java
public class B extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.b, container, false);
Log.d("TAG","fragment2");
return view;
}
}
a.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment1"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="#string/some_text"
android:textSize="20sp" />
<ListView
android:id="#+id/listView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
</FrameLayout>
b.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fillViewport="false">
<AbsoluteLayout
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="218dp"
android:layout_height="47dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Update Page"
android:id="#+id/textView114"
android:layout_x="12dp"
android:layout_y="20dp" />
</AbsoluteLayout>
</ScrollView>
This is how my Fragment A looked like.
When the list is clicked.
What's wrong here :?
in your a.xml use the following :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment1"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="#string/app_name"
android:textSize="20sp" />
<ListView
android:id="#+id/listView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
</FrameLayout>
I think may be your problem in instantiating the EditText fields, you'd better declare your items after the view is created, so you have to override the method onViewCreated and make your declarations in it, then put your database work in a try-catch block to make sure it isn't the reason of any problems:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
name3 = (EditText) view.findViewById(R.id.editText9);
date3 = (EditText) view.findViewById(R.id.editText12);
Bundle bundle = this.getArguments();
date = bundle.getString("date1");
ID = bundle.getString("ID");
RetrievePage(date, ID);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.b, container, false);
return view;
}
public void RetrievePage(String date, String id) {
final String date2 = date;
final String id2 = id;
Log.d("m", id2);
name3.setText("Lim ");
date3.setText(date2);
try {
database = dbHelper.getWritableDatabase();
c = database
.rawQuery(
"SELECT i.Weather FROM Information i LEFT JOIN WorkForce w ON w.TInfo_id = i._id WHERE i.Name = ? AND i._id= ? ",
new String[] { String.valueOf("Lim"),
String.valueOf(id2) }, null);
if (c != null) {
while (c.moveToNext()) {
Info I = new Info();
Force WF = new Force();
String Weather = c.getString(c
.getColumnIndexOrThrow(MyDatabaseHelper.Weather));
}
}
c.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
About fragments overlapping, you must declare each fragment as a separated fragment, and the main FragmentActivity is the activity that holds the fragments which in your case must be an empty activity with only the ViewPager or FrameLayout that contain fragments:
<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"
android:background="#drawable/bg" >
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ac_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.9" />
</RelativeLayout>
So, you must have MainActivity that contains two fragments FragmentA and FragmentB
for reference look at this answer.

using layout file for fragment in Navigation drawer layout

I have an android app code that uses the navigation drawer layout with fragments as the main content.
So far I have had a specific fragment class for all the fragment items in my drawer. Now I do however have a different layout I want to get as an item in my drawer as well. The layout is a LiniarLayout and defined in xml characteristic.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/label_device_address"
android:textSize="18sp"/>
<Space android:layout_width="5dp"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/device_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/label_state"
android:textSize="18sp"/>
<Space android:layout_width="5dp"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/connection_state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/disconnected"
android:textSize="18sp"/>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/label_data"
android:textSize="18sp"/>
<Space android:layout_width="5dp"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/data_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/no_data"
android:textSize="18sp"/>
</LinearLayout>
<ExpandableListView android:id="#+id/gatt_services_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
in my main activity I preload the fragments in the onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//create adapters early
mAdapter = new DeviceAdapter(this, false);
mFilterAdapter = new DeviceAdapter(this, true);
setContentView(R.layout.activity_main);
mFragmentManager = getFragmentManager();
mNavigationDrawerFragment = (NavigationDrawerFragment)
mFragmentManager.findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
mDevices = new HashMap<String, ScanResultContent.BtLeDeviceItem>();
mFilteredDevices = new HashMap<String, ScanResultContent.BtLeDeviceItem>();
//setup fragment 1
mScanResultFragment = new ResultListFragment();
//setup fragment 2
mFilteredScanResultFragment = new ResultListFragment();
mScanResultFragment.setListAdapter(mAdapter);
//setup fragment 3
mDeviceInfoFragment = DeviceInfoFragment.newInstance("");
// Sets up UI references for the Device Info viewer.
mConnectionState = (TextView) findViewById(R.id.connection_state);
mDataField = (TextView) findViewById(R.id.data_value);
mGattServicesList = (ExpandableListView) findViewById(R.id.gatt_services_list);
mGattServicesList.setOnChildClickListener(servicesListClickListner);
mFilteredScanResultFragment.setListAdapter(mFilterAdapter);
// setup default fragment shown
mFragmentManager.beginTransaction().add(R.id.container, mScanResultFragment).commit();
}
I have tried to get the layout loaded into a fragment using the DeviceInfoFragment class:
public class DeviceInfoFragment extends Fragment {
public DeviceInfoFragment(){
super();
}
public static DeviceInfoFragment newInstance(String text) {
DeviceInfoFragment f = new DeviceInfoFragment();
Bundle b = new Bundle();
b.putString("text", text);
f.setArguments(b);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.gatt_characteristics_layout, container, false);
return v;
}
}
I want to be able to switch between the fragments using this (which have worked fine except for the new fragment 3):
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
Fragment f = null;
switch (position+1){
case 1:
f = mScanResultFragment;
mTitle = getString(R.string.title_devicescan);
break;
case 2:
f = mFilteredScanResultFragment;
mTitle = getString(R.string.title_results);
break;
case 3:
f = mDeviceInfoFragment;
mTitle = getString(R.string.title_device_info);
break;
}
if(f != null) {
mFragmentManager.beginTransaction()
.replace(R.id.container, f)
.commit();
}
restoreActionBar();
}
It does however not seem to work as the line:
mGattServicesList.setOnChildClickListener(servicesListClickListner);
fails with
E/AndroidRuntime(30644): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ExpandableListView.setOnChildClickListener(android.widget.ExpandableListView$OnChildClickListener)' on a null object reference
Can anyone tell me what I am doing wrong here?

Moving data from Fragment to new Activity with button click

I have three Framgments inside a Viewpager and I want to start a new Activity from one of them with a button click. I also want to take some information with me from four Spinner elements. I am able to get the information from the Spinners and save in global variables but when I click the button the variables become null. I just can't figure this out and it's driving me mad!
Here is how I make the Fragments and find the correct layout XML:
public class SlideFragment extends Fragment {
private int currentPageNumber;
private View mainView;
public static SlideFragment create(int pageNumber, String origin) {
SlideFragment myFragment = new SlideFragment();
Bundle args = new Bundle();
args.putInt("page", pageNumber);
args.putString("origin", origin);
myFragment.setArguments(args);
return myFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
currentPageNumber = getArguments().getInt("page");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String origin = getArguments().getString("origin");
// This is the mainActivity
Rastimar rastimar = new Rastimar();
if (origin == "profile") {
if (currentPageNumber == 0) {
mainView = inflater.inflate(R.layout.profile_screen1, container, false);
}
else {
mainView = inflater.inflate(R.layout.profile_screen2, container, false);
}
}
else if (origin == "rastimi") {
switch (currentPageNumber) {
case 0:
mainView = inflater.inflate(R.layout.rastimar, container, false);
rastimar.makeSpinners(mainView);
rastimar.makeListView(mainView);
break;
case 1:
mainView = inflater.inflate(R.layout.rastima_leit, container, false);
rastimar.makeSpinnersForRastimaLeit(mainView);
break;
case 2:
mainView = inflater.inflate(R.layout.rastima_yfirlit, container, false);
rastimar.makeExpandableListView(mainView);
rastimar.makeSpinnersForYfirlit(mainView);
break;
}
}
return mainView;
}
}
Here I get the data from the spinners, this works.
private class onSpinnerSelected implements AdapterView.OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
// Find the spinner that was pressed by id
switch(parent.getId()) {
case R.id.dates:
selectedRastimaDate = parent.getItemAtPosition(pos).toString();
break;
case R.id.courses:
selectedCourse = parent.getItemAtPosition(pos).toString();
break;
case R.id.spinner_start_time:
selectedStartTime = parent.getItemAtPosition(pos).toString();
break;
case R.id.spinner_end_time:
selectedEndTime = parent.getItemAtPosition(pos).toString();
break;
case R.id.spinner_dates:
selectedDate = parent.getItemAtPosition(pos).toString();
break;
}
}
public void onNothingSelected(AdapterView<?> parent) {
// Another interface callback
}
}
This is the method that is called when the button is pressed, all the variables in the putExtra method are all of a sudden null:
public void findAvailableTime(View view) {
Intent lausir_timar = new Intent(this, LausirTimar.class);
lausir_timar.putExtra("Date", selectedRastimaDate);
lausir_timar.putExtra("Course", selectedCourse);
lausir_timar.putExtra("StartTime", selectedStartTime);
lausir_timar.putExtra("EndTime", selectedEndTime);
startActivity(lausir_timar);
}
and this is the XML layout file for the Fragment
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="cityboys.golfapp.Rastimar">
<TextView
android:id="#+id/rastimaLeit_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30dp"
android:textStyle="bold"
android:textColor="#2d7165"
android:layout_centerHorizontal="true"
android:text="Rástímaleit"
android:paddingBottom="10dp"/>
<Spinner
android:id="#+id/dates"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/rastimaLeit_title"
android:textColor="#2d7165"
android:layout_marginRight="5dp"
android:layout_alignParentLeft="true"/>
<Spinner
android:id="#+id/spinner_start_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/rastimaLeit_title"
android:textColor="#2d7165"
android:layout_marginRight="5dp"
android:layout_alignParentRight="true"/>
<Spinner
android:id="#+id/courses"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/dates"
android:textColor="#2d7165"
android:layout_marginRight="5dp"
android:layout_alignParentLeft="true"/>
<Spinner
android:id="#+id/spinner_end_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/spinner_start_time"
android:textColor="#2d7165"
android:layout_marginRight="5dp"
android:layout_alignParentRight="true"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Lausir tímar"
android:id="#+id/button"
android:layout_below="#+id/spinner_end_time"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:onClick="findAvailableTime" />
</RelativeLayout>
<!-- The navigation drawer -->
<ListView android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#2d7165"
android:dividerHeight="0.5dp"
android:background="#2b574e" />
I'm not sure what more information I should give so if this is not enough just ask for more!
Thanks in advance.

Categories