I am trying to have an ImageView of a screenshot take up the full screen (including the SystemUi nav bar at the top. I have tried the "Immersive full screen" introduced in Kitkat, and that does take away the UI bar, but my image still does not extend all the way to the top (as seen by the blue bar at the top of the image). The developer site says that it does this so that the image doesn't have to resize when the UI comes back, but it doesn't offer an alternate solution if you don't want the UI visible at all.
screenshot image <- I don't have enough reputation yet to post images.
Here is the code that I have tried (The commented out sections are other options that I have tried that didn't work either):
public class TrickScreen extends AppCompatActivity {
#Bind(R.id.screenshotImage) ImageView mScreenshotImage;
private Uri mMediaUri;
View mTrickScreenView;
RelativeLayout rl;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_trick_screen);
ButterKnife.bind(this);
mTrickScreenView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
int uiOptions2 = View.SYSTEM_UI_FLAG_IMMERSIVE;
int uiOptions3 = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
mTrickScreenView.setSystemUiVisibility(uiOptions | uiOptions2 | uiOptions3);
// requestWindowFeature(Window.FEATURE_NO_TITLE);
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
Intent intent = getIntent();
mMediaUri = intent.getData();
mScreenshotImage.setImageURI(mMediaUri);
// File file = new File(mMediaUri.getPath());
// Drawable drawable = Drawable.createFromPath(file.getAbsolutePath());
// rl = (RelativeLayout)findViewById(R.id.trickRelativeLayout);
// rl.setBackground(drawable);
I figured it out. Recently they have switched the XML format to include two XML docs per activity (e.g. activity_main.xml and content_main.xml). I usually only work in the content file, but you have to also ensure that the code in activity_main.xml is what you need. In my case I needed to remove one line - android:fitsSystemWindow = "true. Once I removed this line, the ImageView extends over the status bar and navigation bar areas.
Related
I've been searching everywhere but I'm at a loss about that : trying to activate immersive mode on a project;
Nearly everything works fine, except the background of my status bar always stays there, spoiling the immersion...
I have included a screenshot of the screen before and after activating the immersive mode, and set the "colorPrimaryDark" to full green for max contrast :
screenshots showing the background of the status bar when nothing should be there
The code I used and reinserted in a blank project to isolate this problem comes straight from the google dev examples, in my MainActivity, I have :
private final String TAG = "DEBUG::" + this.getClass().getSimpleName();
private final int INITIAL_HIDE_DELAY = 1500;
private View decorView;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//setting needed decorView for fullscreen behavior
decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener(onSystemUiVisibilityChangeListener);
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.i(TAG, "onWindowFocusChanged::hasFocus = " + hasFocus);
if (hasFocus) {// When the window gains focus, hide the system UI.
delayedHide(INITIAL_HIDE_DELAY);
} else {// When the window loses focus, cancel any pending hide action.
mHideHandler.removeMessages(0);
}
}
private void hideSystemUI() {
Log.i(TAG, "hideSystemUI");
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
uiOptions |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
uiOptions |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
uiOptions |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
uiOptions |= View.SYSTEM_UI_FLAG_FULLSCREEN;
uiOptions |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
uiOptions |= View.SYSTEM_UI_FLAG_IMMERSIVE;
decorView.setSystemUiVisibility(uiOptions);
}
private final Handler mHideHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
hideSystemUI();
}
};
private void delayedHide(int delayMillis) {
Log.i(TAG, "delayedHide");
mHideHandler.removeMessages(0);
mHideHandler.sendEmptyMessageDelayed(0, delayMillis);
}
private View.OnSystemUiVisibilityChangeListener onSystemUiVisibilityChangeListener =
new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
// The system bars are visible
getSupportActionBar().show();
delayedHide(INITIAL_HIDE_DELAY);
} else {
// The system bars are NOT visible
getSupportActionBar().hide();
}
}
};
I wonder if my problem might come from layout or style files, but those are raw from project generation...
I hope someone out there can point me to where I failed!
Thanks in advance!
EDIT : I found that removing : android:fitsSystemWindows="true" from my activity's layout file allows a real fullscreen mode, but then, my ActionBar is partly hidden behind the StatusBar -when showing. Could it be that when I set my getSupportActionBar().show(); in onSystemUiVisibilityChangeListener, it gets drawn too soon?
EDIT 2 : How I understand this so far is that I only have 2 choices regarding the position/size of my content (action bar included) :
top of the screen, which will show the actionBar partially hidden by the statusbar,
or below the statusBar's bottom, which will leave me with a "hole" when the statusBar is hidden -_-
I am now looking for a solution to animate the ActionBar off-screen/on-screen by myself inside my onSystemUiVisibilityChangeListener method, but can't find a way to grab its View to do so, solutions posted there https://stackoverflow.com/a/21125631/6463888 seem out of date...
I met the same problem today. But I didn't solve this issue by setSystemUiVisibility. I solve it using following method:
hide:enter full screen
mActivity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
show:normal display
mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
So,
the way I solved this may seem a bit stretched, but I'm only a beginner, so feel free to comment!
I don't use getSupportActionBar().show(); or getSupportActionBar().hide(); anymore, but I managed to grab the View that contains the ActionBar which is an AppBarLayout, and I animated this View instead. So I call a small function animateActionBarInOrOut to animate it on or off screen inside onSystemUiVisibilityChange :
private void animateActionBarInOrOut(boolean appears){
Log.i(TAG, "animateActionBarInOrOut::actual position = " + toolbar.getY());
if(appears){
toolbar.animate().translationY(48).alpha(1); // move it out of the screen
}else{
toolbar.animate().translationY(-48).alpha(0); // move it out of the screen
}
}
Although this is not exactly an answer to the initial question, it works as a solution to the problem, one just has to move the content accordingly...
Hi your problem is caused by StatusBar nature, it has a separate layout from your main content and you need to set his color manually. For example when you call onSystemUiVisibilityChange() you can take the color of your background and, after set the color of StatusBar with that color. This is a workaround to avoid 2 different background colors.
I am making an application in android for picture slide show. I have tried the following code:
class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Drawable backgrounds[] = new Drawable[2];
Resources res = getResources();
backgrounds[0] = res.getDrawable(android.R.drawable.btn_star_big_on);
backgrounds[1] = res.getDrawable(android.R.drawable.btn_star_big_off);
TransitionDrawable crossfader = new TransitionDrawable(backgrounds);
ImageView image = (ImageView)findViewById(R.id.image);
image.setImageDrawable(crossfader);
crossfader.startTransition(3000);
}
}
This code successfully bring the new image on top but previous image is not faded out.
Can anyone help me on it?
You need to enable the cross fade on your transition to have both of your images fade. Use the method setCrossFadeEnabled to enable it by setting it tu true.
See documentation here http://developer.android.com/reference/android/graphics/drawable/TransitionDrawable.html#setCrossFadeEnabled(boolean)
I'm using following code for hiding status bar with full screen purpose:
void HideEverything(){
if (Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
View decorView = getWindow().getDecorView();
// Hide the status bar.
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
// Remember that you should never show the action bar if the
// status bar is hidden, so hide that too if necessary.
ActionBar actionBar = getActionBar();
actionBar.hide();
}
}
It shows Screen in full-screen mode but when I touch status bar it shows status bar.
I tried other options to add the full screen and no title bar theme in application and activity level in manifest, but still results are the same... :(
I don't want to show status bar at any step.
How to achieve this in android?
Edit :
Android OS version is 4.4.2
(Above code is working on 4.3 but not on 4.4.2)
Update:
Problem has been solved...
Answer is written below separately...
No solution could work for the problem as Android version is 4.4.2.
As commented by #Academy of Programmer; this solution does not work on Android 6 and above.
But as per the suggestion by Sunny, problem has been solved by preventing the expansion of status bar.
Solution is:
Write an inline customViewGroup class in your main activity.
public class customViewGroup extends ViewGroup {
public customViewGroup(Context context) {
super(context);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v("customViewGroup", "**********Intercepted");
return true;
}
}
Now in your onCreate method of mainActivity add following code before setContentView() :
WindowManager manager = ((WindowManager) getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE));
WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
localLayoutParams.gravity = Gravity.TOP;
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
// this is to enable the notification to receive touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
localLayoutParams.height = (int) (50 * getResources()
.getDisplayMetrics().scaledDensity);
localLayoutParams.format = PixelFormat.TRANSPARENT;
customViewGroup view = new customViewGroup(this);
manager.addView(view, localLayoutParams);
Above code will disable the expansion of status bar.
Now make full screen by following code, add it just below the above code and before the setContentView :
//fullscreen
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
Now in manifest add the permission:
<!-- prevent expanding status bar -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
and you are done.... :)
drawback : This code disables expansion of status bar for the device not just for an activity or an application, so use it if you really need it.
Thank you for all the solutions and suggestions... :)
We cannot prevent the status appearing in full screen mode in kitkat or above devices, so try a hack to block the status bar from expanding.
For an idea, put an overlay over status bar and consume all input events. It will prevent the status bar from expanding.
Using below code you can use full screen ;
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
Write below code above setcontentview.
Note : Don't give any theme to this activity.
Hope this helps.
use following code onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
I am trying new Android L API in particular transitions. The best experience I have with "Fade" but "Slide.RIGHT" behaves really weird… When screen fly in it brings firstly screen title at the bottom, then title jump to the top of the screen and rest of the screen is appear…
I did not use custom transition, just basic one. Screen I use for testing has just couple of TextView, EditText and button. But even if I change Google ActivitySceneTransitionBasicSample from custom transition to basic Slide.RIGHT it behave the same strange way…
Is somebody managed to implement nice Slide transition? In my case I need to Slide completely different screens. There are no elements I can share.
My code is:
First Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
Slide transitionEnter = new Slide();
transitionEnter.setSlideEdge(Gravity.RIGHT);
transitionEnter.setDuration(1000);
Window currentW = getWindow();
currentW.setEnterTransition(transitionEnter);
currentW.setExitTransition(transitionEnter);
getWindow().setAllowEnterTransitionOverlap(true);
getWindow().setAllowExitTransitionOverlap(true);
setContentView(R.layout.slide_test_view);
}
public void buttonLAction(View view){
Utils.startActivity(this, SecondSlideTestActivity.class);
}
Second Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
Slide transitionEnter = new Slide();
transitionEnter.setSlideEdge(Gravity.RIGHT);
transitionEnter.setDuration(1000);
Window currentW = getWindow();
currentW.setEnterTransition(transitionEnter);
currentW.setExitTransition(transitionEnter);
getWindow().setAllowEnterTransitionOverlap(true);
getWindow().setAllowExitTransitionOverlap(true);
setContentView(R.layout.second_slide_test_view);
}
Just a small suggestion, doesn't make it perfect but looks better in my opinion:
Use different edges for enter and exit transition, e.g.:
transitionEnter.setSlideEdge(Gravity.RIGHT);
transitionExit.setSlideEdge(Gravity.LEFT);
I did that and for me it looks kinda okay then. Hope this helps!
My problem is that I have complicated layout, and when my application starts, I see how every view is adding to layout. I see my custom window title bar construction too. I see empty custom window title, with gradient background on start, and then 1 - 2 sec later I see completed window title with my views.
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);
Is there simple way to show white screen, until my activity and custom title bar will be completely constructed?
The main trouble is that I cant start application with no title, and then add custom window title.
Only solution I know is splash screen, but it is too complicated for just this small task.
Use an asynctask like this:
private class LoadingMyView extends AsyncTask<void, void, int> {
protected void onPreExecute ()
{
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);
//show whiteView
}
protected int doInBackground() {
return 0;
}
protected void onPostExecute(int result) {
//Hide white View
}
}
Note: I didnt test the code but i think more or less is ok
AsyncTask