Fragment with TextInputLayout crashes app on Android Marshmallow - android

I've discovered the following issue. I use Material Design' class android.support.design.widget.TextInputLayout in XML layout.
When I inflate this layout in fragment, my app falls with the following error:
android.view.InflateException: Binary XML file line #563: Error inflating class <unknown>
The fall occures on Samsung Galaxy S7 with Android 6.0.1. When I start the app on Lenovo A319 with Android 4.4.2 everything goes fine, no crash.
When I use XML layout with android.support.design.widget.TextInputLayout class for activity (without any fragments), Galaxy S7 works fine too.
It seems that there is something wrong on Marshmallow when app tries to inflate android.support.design.widget classes in fragment.
Is there some way to fix that?
Here is my code:
DocumentEditFragment.java
public class DocumentEditFragment extends BaseFragment {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.fragment_document_edit, container, false); // The app falls here on Galaxy S7
...
}
DocumentActivity.java
public class DocumentActivity extends AppCompatActivity {
private DocumentEditFragment docEditFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_document);
docEditFragment = new DocumentEditFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_document, docEditFragment);
ft.commit();
}
}
fragment_document_edit.xml
<?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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="0dp"
android:layout_margin="0dp"
<ScrollView
android:id="#+id/doc_edit_scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:layout_marginLeft="16dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
>
...
<!-- line #563 is below: -->
<android.support.design.widget.TextInputLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="22dp"
android:layout_marginLeft="60dp"
android:layout_marginRight="16dp"
app:errorEnabled="true"
android:theme="#style/TextLabel"
>
<android.support.v7.widget.AppCompatEditText
android:id="#+id/doc_edit_comment"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="1st line\n2nd line"
android:singleLine="false"
android:hint="Comment"
android:textColorHint="#69202020"
/>
</android.support.design.widget.TextInputLayout>
</ScrollView>
</LinearLayout>
activity_document.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:id="#+id/fragment_document"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="my.app.DocumentFragment"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
tools:context="my.app.DocumentFragment"
/>
UPDATE:
I've uploaded the sample project that produces the same error on Galaxy S7 edge as my working project does (I cannot make public the corporate project). Here is the repository link.
SOLVED
I've moved the attribute
android:theme="#style/TextLabel"
from <android.support.design.widget.TextInputLayout /> into <android.support.v7.widget.AppCompatEditText /> - and everything goes fine! Thanks to Nico from Udacity for wise advice!

Related

Whether the resource id in Android xml can be used before being declared

I wonder that Whether the resource id in Android xml can be used before being declared? when I test it in a demo application , compiled in Android Studio and ran in the phone both work. The xml code in demo as following:
<?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">
<LinearLayout
android:id ="#+id/view"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#color/black"
android:layout_alignBottom="#id/bt"/>
<Button
android:id="#+id/bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" am a button" />
</RelativeLayout>
The Activity code as following:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

RecyclerView Scrollbar is not visible in Dialog Fragment in Android

I have a dialog fragment, in which I have a recycler view. I want to add a scrollbar to the recycler view. I added scrollbars="vertical" but it's not showing up. I think the issue has something to do with the themes.
Here is my xml:
<android.support.constraint.ConstraintLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:padding="16dp"
tools:context="com.airxos.app.common.fragments.LayerSwitcherFragment">
<TextView
android:id="#+id/layer_list_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:fontFamily="sans-serif"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#color/black_87"
android:text="#string/layers"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/layer_list"
android:layout_marginTop="#dimen/margin_16"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/layer_list_title"
app:layout_constraintEnd_toEndOf="parent"
android:layout_height="0dp"
android:maxHeight="#dimen/info_window_height"
android:layout_width="match_parent"
android:nestedScrollingEnabled="true"
android:scrollbars="vertical"
android:background="#color/white"
android:scrollbarThumbVertical="#drawable/scrollbar"
android:scrollbarSize="5dp"
android:padding="5dp"
android:scrollbarStyle="insideInset"/>
</android.support.constraint.ConstraintLayout>
I am restricting the height and width of the dialog fragment as shown below:
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
Objects.requireNonNull(inflater, "LayoutInflater");
if(getDialog().getWindow() != null) {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().setCanceledOnTouchOutside(true);
}
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_layer_switcher, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
Objects.requireNonNull(view, "View");
super.onViewCreated(view, savedInstanceState);
layerList = view.findViewById(R.id.layer_list);
layerList.setAdapter(new LayerListAdapter(context, layers, layerSelectionListener));
layerList.setLayoutManager(new LinearLayoutManager(context));
}
I have already tried everything suggested in this SO question and it did not work.
Other than this I have also tried creating a drawable and adding it as scrollbarThumbVertical
I think it has something to do with the themes because even when I change the background color of constraint layout it is not showing up in the dialog.
EDIT:
I am showing the dialog as shown below:
LayerSwitcherFragment switcherFragment = LayerSwitcherFragment.newInstance(layers);
FragmentTransaction ft = getChildFragmentManager().beginTransaction();
Fragment prev = getChildFragmentManager().findFragmentByTag("layer_dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
switcherFragment.show(ft, "layer_dialog");
EDIT: Issue is solved.
I am sorry for wasting everyone's time. The issue was a stupid mistake we made. My DialogFragment was in a Library. We build the arr file and was using it inside the app. The issue was that we forgot to remove the dialogfragment's XML files from the main app when we refactored it to the arr library. So even after we update the files in the library, the app was picking up the old file in the main app instead of the updated file because the name of the XML was the same.
Try:
android:fadeScrollbars="false"
android:scrollbarAlwaysDrawVerticalTrack="true"
Try This:
In XML:
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:scrollbars="vertical" <!-- type of scrollbar -->
android:scrollbarThumbVertical="#android:color/darker_gray"
android:scrollbarSize="5dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
In your xml, Just set the android:scrollbars="vertical" it can work.
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
I know this can come kind of late. Try to use a NestedScrollView as the parent of the RecyclerView. Like this:
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/layer_list_title"
app:layout_constraintEnd_toEndOf="parent"
android:scrollbars="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/layer_list"
android:layout_marginTop="#dimen/margin_16"
android:layout_height="wrap_content"
android:maxHeight="#dimen/info_window_height"
android:layout_width="match_parent"
android:nestedScrollingEnabled="true"
android:background="#color/white"
android:padding="5dp"/>
</androidx.core.widget.NestedScrollView>
I guess in DialogFragment you scrollbar is transparent
try this code
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/mTaskListRV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbarSize="5dp"
android:scrollbarThumbVertical="#drawable/shape_progress"
android:scrollbarTrackVertical="#drawable/shape_round_gray"
android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="#layout/cash_out_task_list_item_layout" />

No view found for id for fragment, even that the FrameLayout is a child of the main layout

I've created code so that Fragment is added dynamically when I tap on a menu button. However I get the error:
No view found for id 0x7f0d009a (tech.glasgowneuro.attysecg:id/fragment_container2) for fragment XYPlotFragment{a75aa2e #0 id=0x7f0d009a}
I've been through all the other posts here and the std answer is that the Frame layout needs to be child of the main layout. I think I've done that right. Still no id is found.
activity_plot_window.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<tech.glasgowneuro.attysecg.InfoView
android:id="#+id/infoview"
title="Plot Window"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp" />
<tech.glasgowneuro.attysecg.RealtimePlotView
android:id="#+id/realtimeplotview"
title="Plot Window"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp" />
</RelativeLayout>
<FrameLayout
android:id="#+id/fragment_container2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</RelativeLayout><!-- </LinearLayout> -->
main JAVA code of the Activity:
public class AttysECG extends AppCompatActivity {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
setContentView(R.layout.activity_plot_window);
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
....
}
...
case R.id.showplot:
// Create a new Fragment to be placed in the activity layout
XYPlotFragment plotFragment = new XYPlotFragment();
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container2, plotFragment).commit();
The question is why do I get this exception? If I do a findViewById(fragment_container2) then the result is null.
How can I get a valid id for the fragment_container2?
At this point the view is certainly inflated because I trigger this crash long after the app has been started.
I've figured it out. Android studio created two "activity_plot_window.xml" files. One has the suffix _v21 so that there are two versions for the older APIs and the newer ones. It's explained here:
https://developer.android.com/training/material/compatibility.html
I've added the Framelayout to the _v21 file and now it works. See the screenshot. It's very easy to oversee when not expanded (just a grey (2)).
You need to find it through FragmentManager:
getSupportFragmentManager().findFragmentById(R.id.fragment_container2);

How to disable PreferenceFragment transparency?

I guess it's ok to set background color in some average fragment with average layout, but here I've got PreferenceFragment, which layout (PreferenceScreen) doesn't support android:background field. What's a neat way to handle it?
Add following to PreferenceFragment class declaration
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
if (view != null) {
view.setBackgroundColor(getResources().getColor(android.R.color.background_dark));
}
return view;
}
Adding my answer since I had a similar issue with PreferenceFragmentCompat that wasn't quite resolved by just adding a color to the background, and this was a top result while googling the problem.
I had the same issue where using PreferenceFragmentCompat would work, but the settings background was transparent and you could still see views in the underlying activty - changing .add() to .replace() in the getSupportFragmentManger yielded the same overlay.
The solution of changing the background color worked. However, for my build the getColor() method was deprecated. I instead use the following code.
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getListView().setBackgroundColor(Color.WHITE);
}
This solved the transparency issue except for one button, which was still clickable. For the sake of brevity, the issue was I was trying to replace the layout that contained the activity views.
What ended up working was creating an empty layout at the highest order and using .replace() on that layout. The buttons are now covered and no longer clickable.
XML where button was still visible above preferences fragment.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!--I was replacing this layout that had all the activity views-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toStartOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="parent">
<TextView
android:text="Z"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/earth_acc_z"
app:layout_constraintTop_toBottomOf="#+id/earth_acc_y"
app:layout_constraintStart_toStartOf="#+id/earth_acc_y"
app:layout_constraintEnd_toEndOf="#+id/earth_acc_y"
app:layout_constraintHorizontal_bias="1.0"/>
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button" android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/toggleRecording"
app:layout_constraintStart_toStartOf="#+id/toggleRecording"
android:layout_marginStart="8dp"/>
</FrameLayout>
</android.support.constraint.ConstraintLayout>
XML of working example with new empty constraint.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!--FrameLayout with two nested ConstraintLayouts-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toStartOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="parent">
<!--ConstraintLayout with acitivty views-->
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent" android:id="#+id/frameLayout">
<TextView
android:text="Z"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/earth_acc_z"
app:layout_constraintTop_toBottomOf="#+id/earth_acc_y"
app:layout_constraintStart_toStartOf="#+id/earth_acc_y"
app:layout_constraintEnd_toEndOf="#+id/earth_acc_y"
app:layout_constraintHorizontal_bias="1.0"/>
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button" android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/toggleRecording"
app:layout_constraintStart_toStartOf="#+id/toggleRecording"
android:layout_marginStart="8dp"/>
</android.support.constraint.ConstraintLayout>
<!--Preference fragment should replace this empty layout-->
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/preferenceFragment"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
</android.support.constraint.ConstraintLayout>
</FrameLayout>
</android.support.constraint.ConstraintLayout>

Using MPChartLibrary within a fragment

I am working on an Android project and I am trying to implement a Library called MPAndroidChart from https://github.com/PhilJay/MPAndroidChart.
I am trying to implement it in a fragment but I keep getting an error and I cannot see why.
Below is my activity.
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment chartFragment = new ChartFragment();
transaction.replace(R.id.fragmentContainer, chartFragment);
transaction.commit();
}
}
Below is my activities layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="#layout/toolbar" />
<FrameLayout android:id="#+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Below is my Fragment class
public class ChartFragment extends Fragment
{
private LineChart mChart;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.graph, container, false);
return v;
}
}
And below is the layout for the fragment
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.LineChart
android:id="#+id/lineChart1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
At the moment it crashes when it tries to inflate the view in my OnCreateView function.
The error I am getting is:
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.MyCompany.ChartTest/com.MyCompany.ChartTest.MainActivity}:
android.view.InflateException: Binary XML file line #5: Error
inflating class com.github.mikephil.charting.charts.LineChart
I honestly do not see anything that could be wrong.
The only difference I see between the Fragments used in the example project is that they use wrap_content instead of match_parent for the width and height of the chart.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.github.mikephil.charting.charts.LineChart
android:id="#+id/lineChart1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
I've managed to confirm where the problem is.
I have my apps theme defined in a library that is used by my various other apps, but for some reason when referencing the theme from the library when using MPAndroidChartLib I get this exception. If I copy and paste the theme style from my Library and it to my apps own styles file and reference this instead it works fine.
Try this, it may help:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.LineChart
android:id="#+id/lineChart1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
The line:
xmlns:app="http://schemas.android.com/apk/res-auto"
is important.
I hope it helps.
I struggled with this exact issue and finally found a working solution.
The clue was an error message on the design preview of the chart fragment:
The following classes could not be instantiated:
charting.charts.LineChart
Exception Details
java.lang.ClassNotFoundException:
com.nineoldandroids.animation.ValueAnimator$AnimatorUpdateListener
Adding com.nineoldandroids:library:2.4.+ to my project's build.gradle file fixed the issue:
dependencies {
compile 'com.android.support:support-v4:19.1.0'
compile 'joda-time:joda-time:2.5'
compile 'com.nineoldandroids:library:2.4.+'
compile files('libs/MPChart.jar')
}
Adding lines below in onCreate() did the trick for me
getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);

Categories

Resources