I want to add a line above the action bar like in the "pocket"-app. How can i do this?
Here is a picture for example:
Thanks
tomtom
Taking advantage of an Activity's WindowManager, we can draw any view we want on top. Here's some (half-pseudo) code that should help:
// Create an instance of some View that does the actual drawing of the line
View customView = new CustomView(<some context>);
// Figure out the window we have to work with
Rect rect = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
// Make sure the view is measured before doing this
int requestedHeight = customView.getLayoutParams().height;
// setup the params of the new view we'll attach
WindowManager.LayoutParams wlp = new WindowManager.LayoutParams(
rect.width(), requestedHeight,
WindowManager.LayoutParams.TYPE_APPLICATION_PANEL,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
// set the parameters so we fit on the top left of the window
wlp.x = 0;
wlp.y = rect.top;
wlp.gravity = Gravity.TOP;
// finally add it to the screen
getWindowManager().addView(header, wlp);
The only thing to be careful is that you can't run that code from onCreate() or any lifecycle method of the Activity because the Window won't have been created yet (You'll get a BadTokenException). One way might be post a Runnable on the Window's DecorView so that your code to add the CustomView runs after the Window is created:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
getWindow().getDecorView().post(<Runnable that execs code above>);
}
As for the actual CustomView that will display that multi-coloured bar, I feel like that's a good exercise :-)
All you'd need to do is have the onDraw() method use canvas.drawRect() with specific x and widths.
Hope that helps.
What Pocket does
As for how Pocket actually does it. If you use HierarchyViewer on the Pocket app, you'll be able to determine that Pocket uses a custom class for their ActionBar. Since they already rebuild all the features of the ActionBar for their needs, in their case, adding the line is like adding a regular View to some ViewGroup.
Related
I have tried to draw a shape for a long time without an answer. I used setContentView(view) for that view. However, I have another setContentView:
setContentView(R.layout.activity_main);//Buttons, Views from XML...
setContentView( mCustomDrawableView);//Custom Shape
Problem is, it only shows ONE view, the shape. The Buttons defined on XML are gone. Basically whichever setContentView(view) is called last is the only View who is drawed. I've also tried many other ways to draw the shape without an answer that works.
I have seen that multiple setContentView do overlap each other, but this is the only way that partially works. Any way to display both Views or another way to draw a shape and my XML Views?
EDIT:
My shape is made in java, not XML
EDIT 2:
Here is my customShape Class:
public class CustomDrawableView extends View {
private ShapeDrawable mDrawable;
public CustomDrawableView(Context context) {
super(context);
int x = 10;
int y = 10;
mDrawable = new ShapeDrawable(new RectShape());
// If the color isn't set, the shape uses black as the default.
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.setBounds(x,y,x+10,y+10);
}
protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
}
}
OK ... setContentView is something which takes a layout/view/whatever and the input defines the contents of the activity/fragment your are setting it to.
So of course your first call does the whole layout, and the second wipes that and sets the content to what you're sending to it.
The thing is to have your view and then add it to a layout. If you have any view in your initial setContentView xml named (+id) and defined (Layout x = getfromid(r.id.x) you can then add your view to that layout with x.addview(myview) or x.addview(CustomDrawableView(context)).
-edit for clarification-
An Activity/Fragment has a Layout which you set using setContentView. You do this once, normally. A Layout defines where Views are placed.
So, you setContentView(your.xml) in onCreate. If you have a programmatic View class, you can then do two things: add new YourView to a named and specified layout in your act/frag (using any layout defined in xml, passed to your frag/act in the xml passed in setContentView and then defined by Layout x = findViewById(R.id.idoflayoutinxmlinfield 'android:id="#+id/x") in code.
Then you can x.addview(new MyView(context)) or Myview z = new MyView(context) and x.addView(z);
-edit2-
When you get better, you can also just add your custom View to the original layout by adding it to the original xml definition.
-edit3-
Sigh. OK. Here it is:
In your activities java file:
RelativeLayout myRellayout;
#Override
public void onCreate(){
setContenView(your.xml)
myRelLayout = findViewByID(R.id.myrellayout);
myRelLayout.addView(new MyCustomView(this));
//or define your custom view and the add it by:
//MyCustomView mcv = new MyCustomView(this);
//myRelLayout.addView(mcv);
}
And your xml should contain any layout like this:
<RelativeLayout
android:id="#+id/myrellayout"
android:width="whatever"
android:height="whatever"
/>
I want to play a gif animation and this view will move on the screen every second, but if I start an activity I need to add this view again and the position will change.
See the attached image below. I need to stick this over every view. Any way to do it?
Create one BaseActivity for all activities in your app to show Overlay View or Layout.
you can inherit BaseActivity on other Activity
You can add gif supported views or layouts
for example i added overlay_layout in my showOverlay method.
you can call showOverlay method where ever you want to show and you can remove with removeOverlay with conditions.
Please note that showOverlay and removeOverlay should be in BaseActivity
void showOverlay(){
LayoutInflater inflater = activity.getLayoutInflater();
layout = inflater.inflate(R.layout.overlay_layout, null);
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.gravity = Gravity.BOTTOM;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.type = WindowManager.LayoutParams.TYPE_APPLICATION;
final WindowManager mWindowManager = (WindowManager);
activity.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
mWindowManager.addView(layout, params);
}
void removeOverlay(){
windowManager.removeView(view);
}
set this view into WindowManager and it will always show on top
I have a basic android application that has several pages accessible from the home page, anyways I change the layout by doing
public void main(View view) {
setContentView(R.layout.main);
}
and changing the layout to the main game page. Now I want to add characters to it and so I added protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint green = new Paint();
green.setColor(Color.GREEN);
Rect theRect = new Rect();
theRect.set(0,0,canvas.getWidth()/2,canvas.getHeight()/2);
canvas.drawRect(theRect, green);
}
but I only want to call it for the "main" or the scene/layout that the game is played in. It appears to not be called at all and that may be due to the fact that I do not completely understand the relationship between the xml and multiple java files and functions. I'm new to android so this may be a stupid question, I just couldn't find anything with multiple web searches, with no luck.
You can add your game view into activity class:
Class GameView extends View/SurfaceView
{
//-- contains onDraw() method
}
To add this game view into your activity, you have to do
get reference of layout in whioch you want to add this gameview.
eg: LinearLayout layout=(LinearLayout) findViewById(R.id.linearlayout);
Add GameView into this layout
eg: layout.addView(new GameView());
For more detail, you can get reference from http://www.edu4java.com/en/androidgame/androidgame3.html
Hope this helps you
Hello I'm a newbie in android development and I am looking forward a way to change the background color.
Here is my code:
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// View layout = new View(this);
// layout.setBackgroundColor(android.R.color.holo_blue_light);
// View root = layout.getRootView();
// root.setBackgroundColor(android.R.color.holo_green_dark);
View view = this.getWindow().getDecorView();
view.setBackgroundColor(R.color.red);
The problem is with the syntax view.setBackgroundColor(R.color.red);
Try:
view.setBackgroundColor(Color.RED);
view.setBackgroundResource(R.drawable.example);
used this :-
view.setBackgroundColor(ContextCompat.getColor(context, R.color.color_name))
This will choose the Marshmallow two parameter method or the pre-Marshmallow method appropriately.
I'm looking to put an openGL model (via GLSurfaceView) on top of the camera, which has its own SurfaceView. Surely this must be possible, apps like Layar do this.
Here is what I am trying:
public class MainActivity extends Activity {
private CameraSurfaceView mCameraSurfaceView;
private GLSurfaceView mCubeGLSurfaceView;
private FrameLayout mFrameLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
mFrameLayout = new FrameLayout(this);
mCameraSurfaceView = new CameraSurfaceView(this);
mCubeGLSurfaceView = new GLSurfaceView(this);
mCubeGLSurfaceView.setRenderer(new CubeRenderer());
//mCubeGLSurfaceView.setZOrderMediaOverlay(true);
mFrameLayout.addView(mCameraSurfaceView);
mFrameLayout.addView(mCubeGLSurfaceView);
setContentView(mFrameLayout);
}
}
Right now: just the camera shows up. I've read online about the SetZOrderMediaOverlay attribute for GLSurfaceView; setting it TRUE in the above code has the 3D cube show up with a black background (i.e. no camera preview shown).
References:
Here is the Cube OpenGL code I'm using: http://intransitione.com/blog/create-a-spinning-cube-with-opengl-es-and-android/
Here is the CameraSurfaceView code:
https://github.com/davefp/android-camera-api-example/blob/master/src/com/example/cameraexample/CameraSurfaceView.java
Other tests I've tried: changing the addView order of the respective surfaceviews doesn't help; it only shows the camera (I read somewhere changing the addView order may help).
Thanks for any help!
Since you state that only the camera preview is currently visible it may be that you have not ordered your views correctly. This is what I have done to create what you desire.
In the Activity create
instance of MySurfaceView derived from GLSurfaceView
instance of MyCameraPreview derived from SurfaceView
in my Activity's onCreate method I do the following:
mySurfaceView = new MySurfaceView(this);
addContentView(mySurfaceView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
myCameraPreview = new MyCameraPreview(this, myCamera);
addContentView(myCameraPreview, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
Please note that using this method you do not use a layout xml.
This will create your two views on top of each other with the camera preview in the background.
Now you need to get the MySurfaceView to draw a transparent background so the camera preview will show behind the objects you render. If you are using OpenGL ES 2.0 add this to the constructor of your MySurfaceView class.
setEGLContextClientVersion(2);
setEGLConfigChooser(8,8,8,8,16,0);
getHolder().setFormat(PixelFormat.TRANSLUCENT);
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
I just worked through this process myself so I may have missed some details.