How to make the layout visible/gone? - android

I am working on an app using geolocation and I want to set a layout VISIBLE when close to a point and GONE when too far from the point.
This is my xml :
<LinearLayout
android:visibility="gone"
android:id="#+id/slidePane"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
Then I use the ID in the activity as usual :
declare it in the class attribute :
private LinearLayout slidepane;
set it in the onCreate() method :
slidepane = (LinearLayout) findViewById(R.id.slidePane);
And then I try to update it in onLocationChanged() method as follows :
if (InterestPoint.CalculationByDistance(location, new LatLng(47.247801, -1.551883)) < 0.03) {
Toast.makeText(MainActivity.mContext, "InterestPoint close", Toast.LENGTH_SHORT).show();
slidepane.setVisibility(View.VISIBLE);
} else {
slidepane.setVisibility(View.GONE);
}
So the condition is correct since the Toast appears but the layout does not become visible, why?
Thank you.
EDIT : I am using https://github.com/umano/AndroidSlidingUpPanel and try to set the visibility of the second child (the sliding panel). I didn't see anything in the documentation about visibility. I can still access the children of the LinearLayout but not the container itself (and especialy the visibility).

Replace this:
slidepane.setVisibility(View.VISIBLE);
with this:
runOnUiThread(new Runnable() {
#Override
public void run() {
slidepane.setVisibility(View.VISIBLE);
}
});

Make sure you set the visibility of view at the time of initialization.
#Override
protected void onCreate(Bundle savedInstanceState) {
........
slidepane = (LinearLayout) findViewById(R.id.slidePane);
slidepane.setVisibility(View.GONE);
.......
//onLocationChanged() add ->
if (InterestPoint.CalculationByDistance(location, new LatLng(47.247801, -1.551883)) < 0.03) {
Toast.makeText(MainActivity.mContext, "InterestPoint close", Toast.LENGTH_SHORT).show();
slidepane.setVisibility(View.VISIBLE);
} else {
slidepane.setVisibility(View.GONE);
}

Related

Correct way to hide and show widgets?

In my app, I need to show and hide widgets like button and textview at a certain time.
and how I am doing is as the following:
private void hideviews() {
image.setVisibility(View.GONE); ///ImageView
title1.setVisibility(View.GONE);///TextView
title2.setVisibility(View.GONE);///TextView
title3.setVisibility(View.GONE);///TextView
title4.setVisibility(View.GONE);///TextView
title5.setVisibility(View.GONE);///TextView
}
private void showviews() {
image.setVisibility(View.VISIBLE);
title1.setVisibility(View.VISIBLE);///TextView
title2.setVisibility(View.VISIBLE);///TextView
title3.setVisibility(View.VISIBLE);///TextView
title4.setVisibility(View.VISIBLE);///TextView
title5.setVisibility(View.VISIBLE);///TextView
}
I don't think this is the correct way to do this.
Because I don't know how many widgets there will be.
Any guidance on how to correctly show widgets is really appreciated.
Get the reference to root layout, iterate through the childs, check if the view at certain index is instance of EditText(or View that you dont need to hide), if not hide it
RelativeLayout root = findViewById(R.id.root)
for(i=0,i<root.getChildCount()-1,i++){
if(! (root.getChildAt(i) instance of EditText)){
root.getChildAt(i).setVisibility(View.GONE)
}
}
Since you don't know how many testviews will be attached, then I believe that the best approach will be to:
get the reference of the parent view group (that contains all the
textviews),
loop through all the childs using getChildAt,
verify whether the object is an instance of TextView/ImageView and if so set its visibility according to your logic
Instead of hiding every widget separately hide the root layout.
RelativeLayout rootLayout;
rootLayout= (RelativeLayout) findViewById(R.id.root_layout);
and use something like this to control the visibility.
public void setLayoutInvisible() {
if (rootLayout.getVisibility() == View.VISIBLE) {
rootLayout.setVisibility(View.GONE);
}
}
public void setLayoutVisible() {
if (rootLayout.getVisibility() == View.GONE) {
rootLayout.setVisibility(View.VISIBLE);
}
}
Make an array of all the views that you want to show/hide:
View[] views = {image, title1, title2, title3, title4, title5};
and then use this to hide them:
for (View view : views) {
view.setVisibility(View.GONE);
}
and use this to show them:
for (View view : views) {
view.setVisibility(View.VISIBLE);
}
although you can combine the 2 code parts in a single procedure:
void fixViews(int state) {
for (View view : views) {
view.setVisibility(state);
}
}
and call it:
fixViews(View.GONE); or fixViews(View.VISIBLE);

How to programatically add a control as soon as I know parent width?

I have a custom control inheriting from LinearLayout and I want to add a child control to it as soon as I know the size of this custom control.
What's the correct method to do this?
The below code is working fine:
yourView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
//yourView.getWidth()
yourView.getViewTreeObserver().removeOnPreDrawListener(this);
return true;
}
});
Hope this will help.
you have to override onFinishInflate() method inside the custom layout. That is the callback called when all views has been inflated. Use this and addd your views.
This might help:
/**
* Great workaround to get view infos after it has been drawn
*/
mCustomView.post(new Runnable() {
#Override
public void run() {
//The code you want to run
}
});

How to disable user interaction while ProgressBar is visible in android?

I am using a custom ProgressBar. Now while a task is going on, I am showing the progress bar, but user can still interact with the views and controls.
How do I disable the user interaction on whole view just like a ProgressDialog does , when it is visible.
Do I need to use a transparent view on top of main view and show the progress bar on that view and hide that view once a task is completed.
Or just get the id of my parentView and set it disabled ? But then I won't be able to dim the background, just like what happens when a dialog appears on the view/Activity/Fragment. Right?
I just want to know the way to disallow the user from any interaction while the progressbar is visible.
Thanks
Your question: How to disable the user interaction while ProgressBar is visible in android?
To disable the user interaction you just need to add the following code
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
To get user interaction back you just need to add the following code
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
Here is an example:
Note:I am giving you just an example to show how to disable or retain user interaction
Add a progress bar in your xml.Something like this
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/progressBar"
android:visibility="gone"/>
In MainActivity when a button pressed you show the progressbar and disable the user interaction.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.imageView);
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mProgressBar.setVisibility(View.VISIBLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
});
}
And when user backPressed you remove the progressbar again retain the user interaction.Something like this
#Override
public void onBackPressed() {
super.onBackPressed();
mProgressBar.setVisibility(View.GONE);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
If you want to add a feature of disable and greyed out display, you need to add in your xml layout file a linear layout that fills the parent. Set its background to #B0000000 and its visibilty to GONE. Then programmatically set its visibility to VISIBLE.
Hope this help!
I have fixed this issue by adding root layout to the ProgressBar.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:clickable="true"
android:gravity="center"
android:visibility="gone"
android:id="#+id/progress">
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"
android:indeterminateTintMode="src_atop"
android:indeterminateTint="#color/primary"/>
</LinearLayout>
Made the root layout clickable
android:clickable="true"
NOTE: In my main view, I had RelativeLayout as root and have added above-mentioned code inside the root layout at the last position (last child).
Hope this helps!!
just set:
android:clickable="true"
in your xml
<ProgressBar...
Only this makes magic!
To extend (pun intended) on the accepted Answer :
When you use kotlin you can use extension functions. That way you have a quick and nice looking method for blocking and unblocking UI.
fun AppCompatActivity.blockInput() {
window.setFlags(
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
}
fun AppCompatActivity.unblockInput() {
window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
}
fun AppCompatActivity.blockInputForTask(task: () -> Unit) {
blockInput()
task.invoke()
unblockInput()
}
You can use the blocking and unblocking functions in your activity. Also, you can add more functionality like showing a Toast or something.
When using it in a custom view or any other view, you can simply cast the context to activity and use the functions.
Use blockInputForTask to surround simple linear tasks and blockInputand unblockInput when they are needed in different scopes.
You can use blockInputForTask like this:
blockInputForTask {
// Your lines of code
// Can be multiple lines
}
Use document default method progressbar.setCancelable(false)
Make a dialog with transparent background. The issue with getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); is that when app will go in background and come back user will be able to interact with UI components, a lot more handling. So for blocking UI make a transparent dialog and if you want to set time for hide/show. Do this in a runnable thread. So the solution will be
public class TransparentDialogHelper {
private Dialog overlayDialog;
#Inject
public TransparentDialogHelper() {
}
public void showDialog(Context context) {
if (AcmaUtility.isContextFinishing(context)) {
return;
}
if (overlayDialog == null) {
overlayDialog = new Dialog(context, android.R.style.Theme_Panel);
overlayDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED);
}
overlayDialog.show();
}
public void hideDialog() {
if (overlayDialog == null || AcmaUtility.isContextFinishing(overlayDialog.getContext())) {
return;
}
overlayDialog.cancel();
}
}
-------- Timer
Handler handler = new Handler();
handler.postDelayed( () -> {
view.hideProgress();
}, 2000);
Make your parent layout as Relative Layout & add this :
<RelativeLayout ... >
<other layout elements over which prog bar will appear>
<RelativeLayout android:id="#+id/rl_progress_bar"
android:layout_width="match_parent" android:clickable="true"
android:layout_height="match_parent" >
<ProgressBar android:id="#+id/pb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminateOnly="true"
style="#android:style/Widget.DeviceDefault.ProgressBar"
android:theme="#style/AppTheme.MyProgressBar"
/>
</RelativeLayout>
If you have floating buttons in your UI, they still grab all the focus & remain clickable when the progress bar is visible. for this use : (when your prog bar is visible & re-enable them when you make your prog bar invisible/gone)
fb.setEnabled(false);

Android Add Items One By One Into a LinearLayout

I'm new to Android and I'm trying to find out how to do that:
- I have an activity with a ScrollView and inside it I have a LinearLayout (R.id.my_layout)
- I nedd to add TextView programmatically so I'm doing this:
I load the main XML layout via seContentView, I refer to my LinearLayout inside the ScrollView as "mLayout" and so on.
I load a list of names from a file and with a function called populateList()I do:
private void populateList() {
try {
for (final String team : mTeams) {
rCount++;
addRow(team);
}
}
The addRow() method just create a new LinearLayout (mRow), a TextView, 2 Button, add the TextView and the 2 Buttons to the LinearLayout, and then I use addView to add the new mRow to the mLayout.
Everything is working fine, but the ScrollView is shown only when i finished creating the list (so when the populateList() ends). What I would like to do is to show the rows one by one in sequence to give the activty a better look and a bit of animation.
Is there a way to do this?
I hope i was able to explain it :-)
Thank you
new Thread(new Runnable() { // i am creating the new thread
#Override
public void run() {
// so call populateList() function here
}
}).start();
and for your addRow(String string) method the place you call View.addView(); edit it this way and place the following code in your addRow(String string) method
View.post(new new Runnable() {// view here is mlayout the scrollView.
#Override
public void run() {
mlayout.addView(yourview); // note yourview should be final,
//eclipse might help you with that
}
});
remember to declare mlayout globally, so you do not have to attach final

Hiding linear layout on runtime in Android

I am having following layout
<merge>
<LinearLayout
android:id="#+id/ll_main"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>
<LinearLayout
android:id="#+id/ll_sub"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>
</merge>
What I want to do is to show/hide the ll_sub layout on runtime through setVisibility() but it is not working.
When I am setting android:visibility="gone" (also I had checked with invisible) from the xml of ll_sub then it is not displayed on the screen and this time when I use setVisibility() to show this layout on runtime, it is displayed but when I try to hide this layout once it is displayed then it is not hiding.
EDIT
I am trying to show/hide this linear layout on click of a button.
LinearLayout ll;
Button minimize;
int visibility=0;
#Override
public void onCreate(Bundle savedInstanceState)
{
ll=(LinearLayout)findViewById(R.id.ll_sub);
minimize=(Button)findViewById(R.id.minimize);
minimize.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
if(visibility==0)
{
visibility=2;
}
else
{
visibility=0;
}
ll.setVisibility(visibility);
}
});
}
It looks like you're setting the wrong constants for changing view visibility.
GONE == 8
INVISIBLE == 4
VISIBLE == 0
However, you should never rely on the actual values that Android happened to designate to represent their constants. Instead use the the values defined in the View class: View.VISIBLE, View.INVISIBLE, and View.GONE.
// snip...
if(visibility == View.VISIBLE)
{
visibility = View.GONE;
}
else
{
visibility = View.VISIBLE;
}
ll.setVisibility(visibility);
And don't forget to call invalidate() on the view :)
You should use the Constants provided by View
View.INVISBLE, View.VISIBLE, View.GONE
and also invalidate your View

Categories

Resources