Preventing my Activity to change orientation depending on its content - android

In my app MainActivity contains a BottomNavigation, so it can display different tabs. Now my intention was, to force some of them to stay in portrait orientation, regardless of how the user holds the device.
MainActivity.java:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNav = findViewById(R.id.bottom_navigation);
bottomNav.setOnNavigationItemSelectedListener(navListener);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OverviewFragment()).commit();
}
private BottomNavigationView.OnNavigationItemSelectedListener navListener =
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.nav_overview:
selectedFragment = new OverviewFragment();
break;
case R.id.nav_reports:
selectedFragment = new ReportsFragment();
break;
case R.id.nav_settings:
selectedFragment = new SettingsFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, selectedFragment).commit();
return true;
}
};
}
activity_main.xml
<RelativeLayout 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=".MainActivity">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/bottom_navigation"/>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="?android:attr/windowBackground"
app:menu="#menu/bottom_navigation"/>
At least one tab should be displayable in portrait AND in landscape mode. Do I have to add some stuff into the xml, or do some java magic? Thanks in advance!

You can set screenOrientation in AndroidManifest.xml.
<activity
android:name="yourActivity"
android:screenOrientation="portrait"/>
This activity will remain portrait always.
If you need it programatically then you can use this.
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Edit If i understood right, you want make different layout for different orientation.
Then create a layout-land directory and place the landscape layout XML
file in that directory.

To set Orientation, Just add screenOrientation inside your manifest in your activity tag
to set orientation - portrait
<activity
android:name=".YourActivityNAME"
android:theme="#style/AppTheme.NoActionBar"
android:screenOrientation="portrait"/>
to set orientation - landscape
<activity
android:name=".YourActivityNAME"
android:theme="#style/AppTheme.NoActionBar"
android:screenOrientation="landscape"/>
Or you can do this Programmatically by using code below:-
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

Just Use this line with that activity you want to use in portrait mode in manifest.xml
android:screenOrientation="portrait"
like this
<activity
android:name=".app.comman.MainActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateAlwaysHidden" />

Add this line in your activity tag in Menifest file android:screenOrientation="portrait". like below,
<activity
android:name=".MainActivity"
android:screenOrientation="portrait"/>

Put these lines in Manifest so that the screen orientation would be portrait.
<activity
android:name=".MainActivity"
android:screenOrientation="portrait"
android:theme="#style/MyMaterialTheme" />

Related

Android - Preventing duplicate window on Intent & StartActivity

I am trying to solve an issue with my android application.
The issue is that when i start a new instance or class by calling an Intent and StartActivity, a duplicate window or view opens.
I want to keep the same activity or view but execute/run a new class without affecting the view. The intent is simply to execute an extended class but i dont want it recreating or opening a duplicate view.
I have tried using android:Launchmode="singleTop" but to no effect.
I have used the standard android navigation drawer example xml and classes. You will see the content_main.xml contains a viewswitcher which includes 2 other xml files which doesn't need to load a new instance or activity...if that makes sense.
Im not sure if the issue lies with the BeaconTracking.java where it calls the super.onCreate(...) event again maybe causing the parent view to reopen??
Any ideas where i am going wrong?
Thanks in advance!
AndroidManifest.xml
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar">
</activity>
<activity
android:name=".BeaconTracking"
android:label="#string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="#style/AppTheme">
</activity>
MainActivity.java
public class MainActivity extends AppCompatActivity implements ...
public ViewSwitcher switcher;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
...
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.nav_vehicle_tracking) {
Intent intent = new Intent(getApplicationContext(), BeaconTracking.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}
} else if (id == R.id.nav_vehicle_info) {
//SWITCH TO BEACON SCREEN
switcher.setDisplayedChild(2);
}
//CLOSE NAVIGATION DRAWER WHEN BUTTON IS PRESSED
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
BeaconTracking.java
public class BeaconTracking extends MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
switcher.setDisplayedChild(1);
}
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<ViewSwitcher
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="wrap_content"
android:id="#+id/content_frame"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<include
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="#layout/content_beacons" />
<include
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="#layout/content_map" />
</ViewSwitcher>
android:Launchmode="singleTop" will not help here, why do you want to open another activity you can manage it in your current activity with view switcher, still you want to open another activity without duplicate window. In that case you can make the transparent ui of the opening activity.
<activity android:name = "BeaconTracking"
android:label = "#string/app_name"
android:theme = "#android:style/Theme.NoDisplay" >
or with theme #android:style/Theme.Translucent.NoTitleBar"
And replace the parent class to AppCompatActivity of BeaconTracking. But still BeaconTracking activity will be added in back stack.
Each Activity has its own views. If you don't want to open new views, you shouldn't start a new Activity. Just move the functionality of your BeaconActivity into the MainActivity.
Try using android:launchMode="singleInstance" in Manifest.

How to make the 'back-arrow' work in the toolbar?

I have the following part of the xml code that defines my toolbar:
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:columnCount="5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:useDefaultMargins="true"
android:alignmentMode="alignBounds"
android:columnOrderPreserved="false">
<android.support.v7.widget.Toolbar android:id="#+id/toolbar_setting"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"/>
... // other code here
and the code in the SettingsActivity (derived from AppCompatActivity) is as follows:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
// Set toolbar, allow going back.
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_setting);
toolbar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Settings");
When compiling and running the code I see a toolbar as follows:
but a click on the left-arrow does not get me back to the previous menu. What am I missing here?
You can access that little arrow by android.R.id.home :
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
}
return(super.onOptionsItemSelected(item));
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
If you try this code , when you click arrow, it will act like your back button pressed.
in onOptionsItemSelected you need to listen for the click then do something
case android.R.id.home:
// do something with the click
break;
As you need to go one level up, make the following changes in your AndroidManifest.xml.
<activity
android:name=".CurrentActivity"
android:parentActivityName=".OneLevelUpActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".OneLevelUpActivity" />
</activity>
In onCreate() add toolbar.setHomeButtonEnabled(true);
The <meta-data> is to support earlier API versions (<API level 16).

Up Button in Toolbar doesn't do anything

I set up Toolbar in my app (for the first time) but the I can't set the Home (/Up) button to do anything when clicked.
I have 3 activitives (MainActivity , Second , Third) and I've defined the toolbar in all 3 but nothing happens when I click the Home button in each of the activitis I want the button to do his (in my understanding) default action which is go back to the Home Activity which is "MainActivity".
Here is some relevant code:
Toolbar layout (named: app_bar.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/toolBar_background"
android:elevation="5dp"
android:title="#string/app_name" />
</RelativeLayout>
my 3 activities layout xmls:
Activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.example.noamm_000.finaltoolbarproject.MainActivity">
<include layout="#layout/app_bar"/>
//More layout code...
Activity_Second.xml:
<?xml version="1.0" encoding="utf-8"?>
<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="com.example.noamm_000.finaltoolbarproject.Second">
<include layout="#layout/app_bar"/>
//More layout code...
Activity_Third.xml:
<?xml version="1.0" encoding="utf-8"?>
<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="com.example.noamm_000.finaltoolbarproject.Third">
<include layout="#layout/app_bar"/>
//More layout code
Actually all the 3 activities simply include the toolbar layout which names "app_bar.xml".
Here is part of my Mainfest file where I configured the app_parent:
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Second"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
<intent-filter>
<action android:name="com.example.noamm_000.finaltoolbarproject.Second" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".Third"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
<intent-filter>
<action android:name="com.example.noamm_000.finaltoolbarproject.Third" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
and ofcourse parts of my java code for each of my 3 activities:
MainActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar_id);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(true);
mainBtn = (Button) findViewById(R.id.btn_main);
openSecondActivity();
}
public void openSecondActivity(){
mainBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent("com.example.noamm_000.finaltoolbarproject.Second");
startActivity(intent);
}
});
SecondActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
btnSecond = (Button) findViewById(R.id.btn_second);
toolbar = (Toolbar) findViewById(R.id.toolbar_id);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(true);
openThirdActivity();
}
public void openThirdActivity(){
btnSecond.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent("com.example.noamm_000.finaltoolbarproject.Third");
startActivity(intent);
}
});
}
and ThirdActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
toolbar = (Toolbar) findViewById(R.id.toolbar_id);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(true);
}
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.toolbar_menu,menu);
return super.onCreateOptionsMenu(menu);
}
You can see that all 3 Activities "onCreate" functions are pretty much the same..
When I start my app I can see the toolbar in all 3 activities and I can see the back arrow in all but clicking it do nothing.
I know I can set the toolbar.setNavigationOnClickListener but I just want it to make it default action which is go to home activity....
Thank you very much,
Noam
Try like this...
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == android.R.id.home) {
Intent i = new Intent(CurrentActivity.this, HomeActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
return true;
}
return super.onOptionsItemSelected(item);
}
Try this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
//finish(); or Do wahtever you wnat to do
return true;
}
return true;
}
If you are having parent activity,Follow this code,
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
if(NavUtils.getParentActivityIntent(this)== null) {
onBackPressed();
}else{
NavUtils.navigateUpFromSameTask(this);
}
break;
}
return super.onOptionsItemSelected(item);
}
Try this in your activities
#Override
public boolean onOptionsItemIdSelected(int id) {
switch (id) {
case R.id.home:
//do stuff
break;
}
return true;
}
In your case, I recommend to you create a AbstractActivity which inherit all your activities. So you can factor a number of behavior , including management of the toolbar button

Adding ActionBar with the arrow "GoBack" to PreferenceActivity?

I have a PreferenceActivity. I'm looking for a way to add ActionBar with the arrow "GoBack" to it. All the examples I found so far have been, to my mind, overcomplicated because if I had a simple Activity I could add ActionBar to it with one line of java code and that would be it.
I wonder, isn't there a simple way to add ActionBar with the arrow "GoBack" to PreferenceActivity?
UPDATE:
Here's my Preference activity:
public class PreferenceActivity123 extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new MainPreferenceFragment()).commit();
}
public static class MainPreferenceFragment extends PreferenceFragment {
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
}
// Add this in your androidmanifest.xml file
<activity
android:name=".SecondActivity"
android:label="#string/app_name"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
You have to set DisplayHomeasUpEnabled in your actionbar activity like
getSupportActionBar().setDisplayHomeAsUpEnabled(true);//Which will show back button
Define the parent activity in AndroidManifest.xml where the activity(PreferenceActivity) will be called once the back button in the action bar is pressed.
In your definition on the Manifest, add the line:
<activity
android:parentActivityName="com.example.activities.PreferenceActivity"
</activity>
or
Just listen the optionItemSelected method
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, PreferenceActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Edit :
In order to achieve same in Preference activity You need to make custom action bar style with back button in styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="PrefTheme" parent="#android:style/Theme.Holo.Light">
<item name="android:actionBarStyle">#style/PrefActionBar</item>
</style>
<style name="PrefActionBar" parent="#android:style/Widget.Holo.ActionBar">
<item name="android:displayOptions">showHome|homeAsUp|showTitle</item>
</style>
</resources>
Call the style in manifest like :
<application android:theme="#style/PrefTheme">
Call the action bar in activity
getActionBar().setDisplayHomeAsUpEnabled(true);
Just use android.support.v7.widget.Toolbar
public class SettingsActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
Toolbar actionbar = (Toolbar) findViewById(R.id.actionbar);
actionbar.setTitle("Settings");
actionbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_action_back));
actionbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
YourActivity.this.finish();
}
});
}
}
and your activity_settings.xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".SettingsActivity"
tools:menu="settings"
tools:actionBarNavMode="standard"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/actionbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimaryDark"
/>
<FrameLayout
android:id="#id/content"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>

Android Fragment contributes to the Action Bar when not on the screen

If I dynamically add a Fragment (using the FragmentManager) into a container defined in a landscape XML then switch to portrait, that dynamically injected Fragment still exists. It is contributing to the Action Bar even though it is not visible. What is a good way / design to prevent this from happening?
I have tried using isVisible in onCreateOptionsMenu of the Fragment but that causes issues on some Android versions because onCreateOptionsMenu is called before onCreateView which results in false even if the fragment is going to be visible with the current configuration.
Note: I am not handling the configuration myself. I haven't specified configChanges in the manifest and I am not overriding onConfigurationChanged.
Activity:
// inject detail fragment
Fragment detailFragment = getSupportFragmentManager().findFragmentById(R.id.detail_container);
if(detailFragment == null)
getSupportFragmentManager().beginTransaction().replace(R.id.detail_container, DetailFragment.newInstance(id)).commit();
// inject master fragment
if(findViewById(R.id.master_container) != null) {
masterDetail = true;
Fragment listFragment = getSupportFragmentManager().findFragmentById(R.id.master_container);
if(listFragment == null)
getSupportFragmentManager().beginTransaction().replace(R.id.master_container, ListFragment.newInstance(position)).commit();
}
Activity portrait XML
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/detail_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Activity landscape XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:baselineAligned="false">
<FrameLayout
android:id="#+id/master_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<FrameLayout
android:id="#+id/detail_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"/>
</LinearLayout>
The model I'd follow based on your explanation.
public class MyActivity extends Activity {
boolean mMultiPane = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FrameLayout masterContainer = (FrameLayout) findViewById(R.id.master_container);
if (masterContainer != null)
mMultiPane = true;
...
}
}
From then on in your Activity you can use the mMultiPane variable to change the behaviour including changing how the options menu is set up (just have two different menu.xml files or add / remove menu items depending on which mode you're in).

Categories

Resources