Android addView StackOverFlow Error - android

I'm trying to make my own basic 'help overlay'. I have achieved this much so far
this was done by calling the addContentView with an instance of a custom view passed in. However i will only be able to hide the custom view instead of completely removing it after I am done with it.
It is very basic so far so there is no flair or pizazz yet. I am trying to further improve its ease of use. https://stackoverflow.com/a/10217050/3194316 this stack overflow answer suggests setting the content view to a dynamically created Framelayout and inflating the views. I have added the code
FrameLayout layout = new FrameLayout((Context) activity);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
layout.setLayoutParams(layoutParams);
View parentView = activity.getWindow().getDecorView().findViewById(android.R.id.content);
((ViewGroup) parentView.getParent()).removeAllViews();
activity.setContentView(layout);
layout.addView(parentView);
layout.addView(this);
where this is an instance of the custom view that sets the overlay shown below. activity is an instance of the activity in which this is presented in. I was at first getting an error that the parentView already had a parent, so this is why View parentView = activity.getWindow().getDecorView().findViewById(android.R.id.content);
((ViewGroup) parentView.getParent()).removeAllViews(); was added. I am now unforunately receiving a stack overflow error, and I cannot seem to understand why. Is there a better approach to this situation?
SOLUTION
Wrapping everything in a popup window allows the entire overlay to be dismissed properly by the android System.
FrameLayout layout = new FrameLayout(context.get());
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
layout.setLayoutParams(layoutParams);
LayoutInflater inflater = (LayoutInflater) context.get().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
View overlayBase = inflater.inflate(R.layout.help_frame, null, false);
layout.addView(this);
layout.addView(overlayBase);
popupWindow = new PopupWindow(context.get());
popupWindow.setContentView(layout);
popupWindow.setWindowLayoutMode(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
popupWindow.showAtLocation(this, Gravity.CENTER, 0, 0);
context was a class level WeakReference variable for the custom view, instantiated when the constructor was called
In case anyone is interested, here is the code I used to create the popupwindow
Here is the (not final) result

If you want a dynamically appearing View anchored to another View you should use a PopupWindow
Is there a simple example of the PopupWindow class using Android v2.0?

Related

Table in native app and WCAG 2,0

I would like to work out what is required to make a simple standard table in a native android app compliant to WCAG 2.0.
I thinking about the requirement 1.3.1 Info and Relationships: Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text. (Level A)
I habe specially poblems with the requirememt of having headers in tables. I even don't know whether it is possible to reach this aim.
For a example of a simple table I took this one https://developer.android.com/guide/topics/ui/layout/grid.html
Thanks in advance.
Best regards
Petra Ritter, accessibility consultant, Foundation access for all
http://www.access-for-all.ch/en/
It is very simple.
Declare a Popupwindow and View as below.
PopupWindow layoutWindow;
View javaLayoutView;
JavaClassName _activity = this;
Write a Java Void method.
In this method add code below.
below will increase speed. if PopupWindow has a somthing method will not go longer else will go further.
if(layoutWindow != null)
return;
Assiggn Activity to this thread.
_activity = this;
Calling the method from Native side will not run directly because our activity is Native Activity since. So it will execute in Ui Thread.
this.runOnUiThread(new Runnable(){
#Override
public void run(){
// Make a Inflator Layout. Our XML Layout will work on this.
LayoutInflater lF =
(LayoutInflator)getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
javaLayoutView = lF.inflate(R.layout.layoutfile, null);
layoutWindow = new PopupWindow( javaLayoutView, LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
LinearLayout mainLayout = new LinearLayout(_activity);
MarginLayoutParams params = new
MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.setMargin(0, 0, 0, 0);
_activity.setContentView(mainLayout, params);
layoutWindow.showAtLocation(mainLayout, Gravity.TOP, 0, 0);
layoutWindow.update();
}
});
Here your layout file will be executed on LinearLayout doesn't matter what layout you used in XML. Here by changing LayoutParams.MATCH_PARENT you can change the width and height.
The line layoutWindow.showAtLocation(mainLayout, Gravity.TOP, 0, 0); will make render your layout over Native Activity,
Remember that If you change anything after layoutWindow.update() must recall it to take effect.
This will damn sure work !!!

open activity as popupwindow with transparent background

Helloo
I have simple question about popupwindow.
If click on button i want open activity as popupwindow with numberpicker . Values in numberpicker i need pass from activity. How to achieve pass values i think i should extend PopupWindow class and create custom PopupWindow or is another solutiion. Thank the cose is as follow
ViewGroup parent = (ViewGroup) view.getParent();
final View v = getLayoutInflater().inflate(R.layout.activity_duration, parent, false);
np = (NumberPicker)findViewById(R.id.durationPicker);
popupWindowDuration = new PopupWindow(v, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true);
popupWindowDuration.showAtLocation(findViewById(R.id.main_content), Gravity.CENTER, 0, 0); here
Already set at manifest
<activity android:theme="#android:style/Theme.Dialog">
And second is how to set background transparent . Becase this code hide previous popupwindows.
Set following code in your second activity's onCreate method below setContentView
getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));

How can I set the LayoutParams of an View Programmatically?

You know this JoystickView from http://code.google.com/p/mobile-anarchy-widgets/wiki/JoystickView ?
Well, I tried to implement it. No Problems with it. I couldn't change It's size because I Added It programmatically. I somehow found out how to change the size, but now It's stuck in the upper left corner and everything I found for three hours got me a NullPointerException on the LayoutParams param I've created or was rejected because It wasn't castable or something to begin with.
public class GameActivity extends Activity implements JoystickMovedListener{
private GraphicsHolder mGraphicsHolder;
private String TAG = "GameActivity";
/*
* creates a new GraphicsHolder and sets it its ContentView
* the GraphicsThread is being included in the GraphicsHolder
*/
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
Log.d(TAG, "created");
FrameLayout gameScreen = new FrameLayout(this);
mGraphicsHolder = new GraphicsHolder(this);
JoystickView Joystick = new JoystickView(this);
// I need to set the Gravity HERE
Joystick.setLayoutParams(new RelativeLayout.MarginLayoutParams(500,500));
gameScreen.addView(mGraphicsHolder);
gameScreen.addView(Joystick);
setContentView(gameScreen);
}
}
Now Here's my Question: can you somehow set the Gravity of this View programmatically?
You can try this
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(500,500);
params.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
Joystick.setLayoutParams(params);
Try to set gravity center to FrameLayout and use ViewGroup.LayoutParams set Joystick LayoutParams :
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.MATCH_PARENT);
params.gravity = Gravity.CENTER;
gameScreen.setLayoutParams(params);
Joystick.setLayoutParams(new ViewGroup.LayoutParams(500,500));
try this.
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) Joystick.getLayoutParams();
params.gravity = Gravity.TOP;// desired gravity
Joystick.setLayoutParams(params);
dont change ur code just add this after setContentView(gameScreen); hope it works
Well, I found the answer, but it's a completely different approach, since none of the above or those I found elsewhere worked for me.
I did the following changes in the onCreate method:
mGraphicsHolder = new GraphicsHolder(this);
LayoutInflater inflate = (LayoutInflater)
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
setContentView(mGraphicsHolder);
getWindow().addContentView(inflate.inflate(
R.layout.controllayout, null), new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT));
Joystick = (JoystickView) getWindow().findViewById(R.id.joystickView1);
Joystick.setOnJostickMovedListener(this);
Now I got my Joystick on an XML Layout, but It actually works (at least in my case where nothing else worked), and it's quite easy to make changes in things of Layout etc.

How to dynamically wrap root layout in a ScrollView

I want to add a scroll view to all the layouts that I have. But dynamically. Because the app will run in different screen sizes, and when I will get a screen size smaller than a specific size, then I want to show the layout in a scroll view.
So I made this method, it will be called on the check that the screen is small. I will pass my activity and I want to change the root layout to scroll view or just add a ScrollView as the root layout. So if the root layout is a LinearLayout, then I want to put that layout in the ScrollView. And I have not named all the layouts, meaning that I didn't give an ID to the layout, so I cannot use findViewById.
public static void SetActivityRoot(Activity c) {
View v = c.getWindow().getDecorView();
// View v = v.getRootView();
ScrollView sv = new ScrollView(c);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
sv.setLayoutParams(lp);
((ViewGroup)v.getParent()).removeView(v);
sv.addView((View) v);
((ViewGroup)v.getParent()).addView(sv);
}
It's giving me an error saying that "you cannot remove view from null" etc. Or that "you cannot add view to layout as it already has parent view". How can I make this work?
Finally solved my problem.
public static void SetActivityRoot(Activity c) {
View v = ((ViewGroup)c.findViewById(android.R.id.content)).getChildAt(0);
ScrollView sv = new ScrollView(c);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
sv.setLayoutParams(lp);
((ViewGroup) v.getParent()).removeAllViews();
sv.addView((View) v);
c.addContentView(sv, lp);
}

Android VideoView: video goes black after being removed from parent view

I am currently playing an rtsp live streaming source using a VideoView. This works fine.
The VideoView is initially inside a fragment with other elements, in 'normal' state, and I am trying to implement a fullscreen toggle button.
To go to fullscreen mode, I am removing the VideoView from its parent (a LinearLayout), and then adding it to another LinearLayout, added on top of everything else using getActivity().addContentView(), here's the code:
LayoutInflater lf = getActivity().getLayoutInflater();
vFullScreen = lf.inflate(R.layout.full_screen, myViewGroup, false);
LinearLayout fullscreenCont = (LinearLayout) vFullScreen.findViewById(R.id.fullscreen_container);
((ViewGroup) vsPlayer.getParent()).removeView(vsPlayer);
fullscreenCont.addView(vsPlayer);
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
getActivity().addContentView(vFullScreen, params);
The problem is that the video goes black once it's removed from the original parent view.
What I'm trying to achieve it's to preserve the video instance to avoid having to reconnect/buffer again, but I don't know how to preserve the video playback during this switching of parents, any ideas?
EDIT:
If I suspend the videoView and then resume it, like this:
LayoutInflater lf = getActivity().getLayoutInflater();
vFullScreen = lf.inflate(R.layout.full_screen, myViewGroup, false);
LinearLayout fullscreenCont = (LinearLayout) vFullScreen.findViewById(R.id.fullscreen_container);
vsPlayer.getVideoView().suspend();
((ViewGroup) vsPlayer.getParent()).removeView(vsPlayer);
fullscreenCont.addView(vsPlayer);
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
getActivity().addContentView(vFullScreen, params);
vsPlayer.getVideoView().resume();
the video play is interrupted (goes black for a few noticeable seconds) but then resumes, wich is a lot better, not perfect because it takes too long to resume play.
Another not so good part is that the methods suspend() and resume() of the class VideoView are available from API level 8 and up, and I need to be compatible with API level 7
Is your problem that the VideoView you're using goes black and temporarily lingers in between the switching of the views?
If so, I've been trying to figure out the cause of that issue for a solid week now. I haven't been able to figure out the actual cause, but my workaround does prevent the VideoView from persisting through screen changes:
public void hideVideoView(){
runOnUiThread(new Runnable() {
public void run() {
findViewById(R.id.yourVideoView).setVisibility(View.INVISIBLE);
}
});
}
I'm basically just setting the view to invisible whenever the view gets switched, and if the view is reloaded I just set it back to View.Visible
This probably won´t :) resolve your problem, but you could seek to the position you where at before removing the VideoView:
long progress = vsPlayer.getCurrentPosition();
LayoutInflater lf = getActivity().getLayoutInflater();
vFullScreen = lf.inflate(R.layout.full_screen, myViewGroup, false);
LinearLayout fullscreenCont = (LinearLayout) vFullScreen.findViewById(R.id.fullscreen_container);
((ViewGroup) vsPlayer.getParent()).removeView(vsPlayer);
fullscreenCont.addView(vsPlayer);
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
getActivity().addContentView(vFullScreen, params);
vsPlayer.seekTo(progress);
I actually had the same issue some time ago.. What i ended up doing was to change the layoutparams of the VideoView to match_parent instead of removing it.
mVideoView.getLayoutParams().width = LayoutParams.MATCH_PARENT;
mVideoView.getLayoutParams().height = LayoutParams.MATCH_PARENT;

Categories

Resources