Consider this example:
There is a minimal activity in android which inflates this layout as root:
<!-- FILE activity_preference.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/settings_container"/>
</LinearLayout>
In the activity's onCreate:
setContentView(R.layout.activity_preference);
Then I want to replace settings_container with my PreferenceFragmentCompat.
I'm using the current androidx Jetpack library, this goes into the app's gradle file:
implementation 'androidx.preference:preference:1.1.0'
I've also created a custom PreferenceFragmentCompat for my needs, but it does not really do too much now:
public class MyPreferenceFragmentCompat extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
// get the screen
PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(getContext());
// add item(s)
CheckBoxPreference item_Confirmation;
item_Confirmation = new CheckBoxPreference(this);
item_Confirmation.setKey("config_Confirmation");
item_Confirmation.setTitle("Confirmation");
item_Confirmation.setSummary("Confirmation");
item_Confirmation.setDefaultValue(false);
preferenceScreen.addPreference(item_Confirmation);
// set this screen as default
setPreferenceScreen(preferenceScreen);
}
Here is how activity transacts my fragment:
getSupportFragmentManager().beginTransaction().replace(R.id.settings_container, new MyPreferenceFragmentCompat()).commit();
However a wide margin gets inserted in front of the CheckboxItem:
How can I eliminate this margin or padding?
If you are using AndroidX, you can use Preference.setIconSpaceReserved(boolean iconSpaceReserved) method.
So, you will have:
item_Confirmation.setIconSpaceReserved(false);
You can also check this answer.
Related
I have a project with Fragments and Activities. I want to try Navigation element, but I can't add Fragments on my graph - in the destination list, I have only Activities. Why does it happen?
Androidx, Java.
UPD: I can't find the correct tag for this navigation element, so only the Android tag present.
Gragle:
implementation 'android.arch.navigation:navigation-fragment:1.0.0'
implementation "android.arch.navigation:navigation-ui:1.0.0"
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".ui.MainActivity">
<fragment
android:id="#+id/my_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/main_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
The screen where I have no Fragments on the destination list:
And, I think it can be important, my preview of MainActivity:
I don't know why, but it gray.
UPD1: red mark on last screen is:
A <fragment> tag allows a layout file to dynamically include different layouts at runtime. At layout editing time the specific layout to be used is not known. You can choose which layout you would like previewed while editing the layout.
I think it's explain why my fragment grey on preview - layout is unknown on runtime. So, my problem is not connecting with it.
It's resolve itselfs when i create one fragment by hands on my navigation graph, and do "Invalidate/restart".
To resolve this issue you have to add tools:layout line to your fragment tag: tools:layout="#layout/fragment_sample_name"
It should looks like this in navigation graph code view
<fragment
android:id="#+id/sampleFragment"
android:name="com.example.sampleFragment"
android:label="#string/sample_name"
tools:layout="#layout/fragment_sample">
</fragment>
Be sure navigation tag have xmlns:tools="http://schemas.android.com/tools" added
<navigation 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:id="#+id/nav_sample_stackoverflow"
app:startDestination="#id/sampleFragment">
I have two activities with same bottom bar.
The problem is when i call to startActivity from Activity A to Activity B has some blink and is not looking so smooth.
for example what I want is like Activity with a container with two fragments and the activity has the bottom bar so this will not change the bottom bar.
I know Activity with Fragments can help me with that but is too complicated to change it on my project so is the last option for me.
I find one more option to do it with SharedElements transition but is supported only from api 21 (Lollipop).
This is my activities and I need the LinearLayout on bottom stay sticky when i change it to Activity B.
You can set up activity animations:
startActivity();
overridePendingTransition(R.anim.hold, R.anim.fade_in);
Please, refer to this answer: stackoverflow
you can remove the defulat transtion between activites.
try this under yourProject/res/values/styles.xml:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowAnimationStyle">#null</item>
</style>
If you want the same instance you will have to use fragments.
If not you could just put that LinearLayout to both layout files.
Which one do you want?
You need create a layout and include ex. bottombar.xml in layout folder and create the layout.
<include layout="#layout/bottombar"/>
if you dont want look delay in change you need use fragments.
To manage fragment, i recommended use FragNav
With this library manage fragments its very easy, remove animation is not solution to your problem
I have made an Activity with two fragments.
In Activity class ,I have write this code for commonBottomSheet :-
BottomSheetBehavior mBottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottom_pannel_layout));
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
mBottomSheetBehavior.setBottomSheetCallback(mBottomSheetCallback);
In Activity xml file in Co-ordinator layout I have included below layout :-
<include layout="#layout/bottom_sheet_pannel"/>
In CommonBottomSheetFragment, you can create your layout .
And my xml file (bottom_sheet_pannel) for bottomSheet is like this :-
<?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:id="#+id/bottom_pannel_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:behavior_peekHeight="45dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<ImageView
android:id="#+id/grabber_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="#drawable/ic_vector_slider_grabber"
android:tint="#color/colorTint" />
<fragment
android:id="#+id/rf_common_details_fragment"
android:layout_marginTop="#dimen/margin_10"
android:name="com.fragment.CommonBottomSheetFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
you can change state of bottomSheet with below callBack :-
private BottomSheetBehavior.BottomSheetCallback mBottomSheetCallback = new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(View bottomSheet, int newState) {
// do what you want on state change
}
#Override
public void onSlide(View bottomSheet, float slideOffset) {
}
};
I'm trying to make a bottomsheet using google support library. The goal is to have a sheet that:
Can be hidden programmatically only
Its height is calculated automatically
Is defined statically in xml
So far so good, simple stuff. There is also this promising isHideable() which defaults to false.
But the bottomsheet seems to ignore the isHideable when the sheet is set to STATE_EXPANDED (although its not going to cover the whole screen). The only way to make it unhideable is to set a peek height (which I don't want). Is there a way to have it expanded and not-hideable without setting the height manually (or via layout change triggers)
Here is the (super slim) code used:
Activity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View bottomSheet = findViewById(R.id.bottomsheet);
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setHideable(false);
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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">
<LinearLayout
android:id="#+id/bottomsheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:behavior_hideable="false"
app:layout_behavior="#string/bottom_sheet_behavior"
android:background="#android:color/white">
<TextView
android:layout_width="match_parent"
android:layout_height="300dp"
android:text=":) :) :)"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
Behavior
The simplest but hackish way I've found so far:
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
bottomSheet.post(new Runnable() {
#Override
public void run() {
behavior.setPeekHeight(bottomSheet.getHeight());
}
});
And of course when there is need to hide it firstly call setHideable(true).
This is just a workaround that might lead to weird behavior.
I'm building a PrefenceFragment but I've a problem to inflate a custom layout within the fragment.
Pratically, I created a custom layout to inflate but doesn't works (the layout was not inflated). I'm trying some solutions but I don't understand where I wrong...
This is my sample code:
public class MyPreferenceFragment extends PreferenceFragment
{
private ListView listjob;
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
LayoutInflater inflater = (LayoutInflater)getActivity().getSystemService(LAYOUT_INFLATER_SERVICE);
View viewlist = inflater.inflate(R.layout.pref_listview_job, null);
TextView txtProva = (TextView)viewlist.findViewById(R.id.txtProva);
txtProva.setText("This is a text");
}
}
This is my custom layout pref_listview_job.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/txtProva"/>
</LinearLayout>
Thanks!
If you extend PreferencesFragment, you need to consider doing two things:
Create an XML file describing your settings screen. This is not a standard layout file.
You need to use addPreferencesFromResource(R.xml.preferences) method to inflate this preferences XML file.
Here is a link to documentation with the XML file and method I mentioned:
http://developer.android.com/reference/android/preference/PreferenceFragment.html
If you need a custom preferences page, then you have two options. Either you use PreferencesFragment with customer preferences, or you extend a non-preference Fragment (e.g. ListFragment) and implement all preferences as standard views.
I've been trying to get Roboguice to work with fragments declared in a <fragment> block in the layout file and then injected into the activity, but, although the fragment exists somewhere off screen (an EditText in the fragment takes focus and fires events), It is not visible. Does RoboGuice support what I'm trying to do here or should I go about it a different way?
code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:id="#+id/myFragment"
android:name="com.example.MyFragment"
android:layout_height="0dp"
android:layout_width="0dp"
android:layout_weight="1" >
<!-- Preview: layout=#layout/my_fragment -->
</fragment>
</LinearLayout>
Java:
#ContentView(R.layout.participant)
public final class Main extends RoboFragmentActivity {
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#InjectFragment(R.id.myFragment) private MyFragment myFragment;
}
Solved the issue, but for anyone else looking - The issue at hand was completely unrelated to RoboGuice, which allows fragment injection exactly as shown above. Rather the issue was that both of my layout dimensions for the fragment were set to 0dp, ensuring that my fragment would never be rendered.