Is it possible to set the visibility of the MainActivity page in android to invisible or make it transparent may be? I have tried setting the visibility to invisible and also made height width as 0dp but this still shows the mainactivity with a white background and blue header.
What I am trying to achieve is, I am opening a floating window which is draggable on click of a button in the mainactivity, but I want to directly open the floating window by triggering the button click from the code itself. This works but the mainactivity still shows up for a second before the floating window is opened. I want to make the mainactivity page invisible or transparent so the mainactivity page is not noticeable.
Here is the XML of mainactivity.xml ,
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="Invisible"
android:background="#color/material_on_primary_disabled"
tools:context="com.example.widget_android.MainActivity">
<Button
android:id="#+id/open_widget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="Open Widget" />
on click of open_widget(which is triggered from code rather than the user having to click on it) the floating window is opened up.
I want to take the user directly to the floating window rather than the landing page which is the mainactivity page.
Here is what is happening on the backend java code
findViewById(R.id.open_widget).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startService(new Intent(MainActivity.this,WidgetService.class));
finish();
}
});
findViewById(R.id.open_widget).performClick();
The reason you get a white screen is because that is the default behaviour. You've tried to put an invisible, transparent, or non-existing (size of 0 pixels) View on top of the default View, so you are still seeing the default View. What you need to do is to replace the default View with a transparent View.
See How do I create a transparent Activity on Android? for information on how to get a transparent Activity.
Related
Background
I have a rather complex layout being shown to the user in an activity.
One of the views is an EditText.
Since I had to make one of the views stay behind the soft-keyboard, yet the rest above it, I had to listen to view-layout changes (written about it here).
The problem
I've noticed that whenever the EditText has focus and shows its caret, the entire view-hierarchy gets re-layout.
You can see it by either looking at the log of the listener I've created, or by enabling "show surface updates" via the developers settings.
This causes bad performance on some devices, especially if the layout of the activity is complex or have fragments that have complex layouts.
The code
I'm not going to show the original code, but there is a simple way to reproduce the issue:
activity_main.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.user.myapplication.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="just some text"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="phone"
android:text="write here"
android:textSize="18dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="just some text 2"/>
</LinearLayout>
</FrameLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(android.R.id.content).getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
#Override
public boolean onPreDraw() {
Log.d("AppLog", "onPreDraw");
return true;
}
});
}
}
What I've tried
When disabling the caret (using "cursorVisible", which for some reason is called a "cursor" instead) , I can see that the problem doesn't exist.
I've tried to find an alternative to the built-in caret behavior, but I can't find. Only thing I've found is this post, but it seems to make it static and I'm not sure as to how well it performs (performance and compatibility vs normal caret).
I've tried to set the size of the EditText forcefully, so that it won't need to cause invalidation of the layout that contains it. It didn't work.
I've also noticed that on the original app, the logs can (for some reason) continue being written even when the app goes to the background.
I've reported about this issue (including sample and video) here, hoping that Google will show what's wrong or a fix for this.
The question
Is there a way to avoid the re-layout of the entire view hierarchy ? A way that will still let the EditText have the same look&feel of normal EditText?
Maybe a way to customize how the EditText behaves with the caret?
I've noticed that whenever the EditText has focus and shows its caret,
the entire view-hierarchy gets re-layout.
This is not true. Size and position of EditText is constant - there is no re-layouting. You can check it by using code below.
findViewById(android.R.id.content).getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Log.d("AppLog", "Layout phase");
}
});
Because of blinking caret - EditText constatly calls invalidate(). This forces the GPU to draw EditText again.
On my nexus 5 (marshmallow) I see that only EditText beeing redrawn (Show GPU view updates - enabled).
How about overriding dispatchOnPreDraw() all the vies you use in activity and having flag to check whether that specific view needs to redraw ?
As you need to disable redraw of all other views only when a text view is on focus. So when a text view is on focus have a flag to disable the redrawing of other views.
if dispatchOnPreDraw() method returns false then refreshing of view will be continues else not. I don't know how complex is your layout and how many views are used, but here a separate class should extent a view used and override that method, and also need a mechanism/variable to distinguish the object in current focus.
Hope this method helps!
let's say I have a view that is made up of 2 layers -> top layer and bottom layer. I place them both in a frame layout.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- bottom layer -->
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/some_image_you_shouldnt_shrink"/>
<!-- top layer -->
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/somewhat_transparent"/>
</FrameLayout>
now, presumably, when i tap on the editText, the keyboard will pop up, and shrink the size of the edit text. However, it seems that the bottom layer is ALSO getting resized. How do i prevent this bottom layer from getting resized?
Note: the framelayout is in a fragment, and the activity that holds this fragment must declare android:windowSoftInputMode="adjustResize".
EDIT*********
Just to clarify, i want the editText layer to adjust as high as the keyboard needs to. however, i don't want the image behind it to adjust at all
i only have 1 activity that handles these similar types of fragments.
You can't prevent a single view from resizing if you set android:windowSoftInputMode="adjustResize". But if you just want to set a non-resizing background, there is a work-around. Instead of setting the background image in the ImageView through XML, add this in your onCreate() method
getWindow().setBackgroundDrawableResource(R.drawable.some_image_you_shouldnt_shrink);
try this in the manifest
android:windowSoftInputMode="stateVisible|adjustPan"
I have created custom tab bars by following the post given below:
How to create a Tab-like UI in Android?
No I need to display a set on sub menu when the center tab (actually it is a button) is clicked. I need the sub menu to pop up like in this drawing (sub menu should be above my main layout):
I believe that this can be achieved by putting an additional layout above the custom tab bar in which a set of buttons can be placed one after another. But I am not sure which layout needs to be used and how I can get the same style in the drawing. Please help me to find a solution.
you're correct with just adding another layout above the button you want to open it, and then setting its visibility to gone until you want to animate in it.
a regular LinearLayout would work fine, and then adding 4 buttons to it would work as well, then you would want to make sure those buttons used the same styles as the built-in android menu buttons (or style it yourself) but check out some of the built in styles here
example:
your activity
<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">
//all your other activity layout stuff goes here
<!--add your new menu-->
<LinearLayout
android:id="#+id/my_menu_layout"
android:visibility="gone"
... />
<Button
android:id="#+id/menu_btn_1"
style="#android:style/Widget.Holo.ActionButton.TextButton" //as example of built-in style
... />
//more buttons
</LinearLayout>
then in your activity class, assign an onClickListener to the button that will toggle the menu and animate the view in
//animation xml you make
Animation inFromBottom = AnimationUtils.loadAnimation(this, R.anim.layout_in_bottom);
mMenuLayout.startAnimation(inFromBottom);
mMenuLayout.setVisibility(View.VISIBLE);
now your view will animate in and you can go about adding onClick listeners to the buttons
I want to display an image preview over my app: when user presses an item in the listview (each item is a path to an image stored in sd card) image preview appears,stretched in the available space, like in this picture (image space is black, underlying app, still partially visible, is gray):
when user presses back image disappear.
I thought to make an activity just for image displaying but I don't know how to obtain the result in the picture...
Edit:
Ok here's what I've done so far:
1)Manifest:
<activity
android:name=".ImageDialogActivity" android:theme="#android:style/Theme.Dialog">
</activity>
2)Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
3)Activity onCreate method:
super.onCreate(savedInstanceState);
setContentView(R.layout.image_preview);
String filepath = getIntent().getStringExtra("image_filepath");
((ImageView)findViewById(R.id.imageView)).setImageBitmap(getBitmap(filepath));
where getBitmap is a private method which gives me a bitmap from a filepath.
Problem is that I don't have control over dialog dimensions: dialog's width and height seem to depend on contained image ones...not to mention top/right/left/bottom margins...
Solved (maybe):
I modified layout file this way:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="200dp"
>
<ImageView android:id="#+id/imageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerInside"/>
Setting width/height to a square allowed to obtain the effect...my question is: will it work for every phone?Or it is right just for mine?
Your best shot is to display your image in a Dialog
If you then want more control over the display, theme it
If you want to do this by creating a new Activity, you should set its layout parameters to wrap_content so it will appears above the other activity but not fitting the screen totally. Also by setting its theme as Theme.Dialog or an inherited theme, you 2nd activity will be a little bit darker and your activity will appear like a dialog.
You should also try to put layout parameter to fill_parent and add margins if you want the exact result as you shown (don't know if this solution could work).
this is from api demos creating an activit like a dilog try this
public class DialogActivity extends Activity {
/**
* Initialization of the Activity after it is first created. Must at least
* call {#link android.app.Activity#setContentView setContentView()} to
* describe what is to be displayed in the screen.
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
// Be sure to call the super class.
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_LEFT_ICON);
// See assets/res/any/layout/dialog_activity.xml for this
// view layout definition, which is being set here as
// the content of our screen.
setContentView(R.layout.dialog_activity);
getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
android.R.drawable.ic_dialog_alert);
}
}
Solved, solution entered in main post seems working fine!
I would like to obtain the same effect as when a modal dialog is displayed, i.e. dimmed background, can't interact with it, but to have a layout element, or more, active "on top" of the rest. For example: I tap on an icon and a panel with detailed information appears from the left, and you can do some stuff on that panel, the rest of the screen is dimmed, inactive. How can I do this? Thanks.
You can start a new Activity with the background set to transparent on some elements, for example:
<ScrollView
android:gravity="left"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#android:color/transparent">
There is also an example of a TranslucentActivity in the Android API Demos:
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/TranslucentActivity.html