I have my android webView app working nice. It also shows the ProgressBar while loading the url and hides it when finish the load with a beautiful effect cause I put some alpha in the ProgressBar layout to see webView in the background. I followed this example..
My problem is: webView is still clickable.
MyManifest.xml: i have all permissions needed I think...
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="21" />
main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/mainLayout"
tools:context="com.siconet.axa.MainActivity" >
<RelativeLayout
android:id="#+id/loadingPanel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" >
<ProgressBar
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:indeterminate="true" />
</RelativeLayout>
<WebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Then I show/hide progressbar in the client and I need to avoid webView from being clicked:
webViewClient.java
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon)
{
loadingFinished = false;
// this works like charm
activity.findViewById(R.id.loadingPanel).setVisibility(View.VISIBLE);
activity.findViewById(R.id.webView).setAlpha(0.3f);
// this is not working :(
activity.findViewById(R.id.loadingPanel).setClickable(true);
activity.findViewById(R.id.webView).setClickable(false);
super.onPageStarted(view, url, favicon);
}
#Override
public void onPageFinished(WebView view, String url)
{
// control of the loading options....
if (loadingFinished && !redirect) {
activity.findViewById(R.id.loadingPanel).setVisibility(View.GONE);
activity.findViewById(R.id.webView).setAlpha(1f);
// not working again :(
activity.findViewById(R.id.loadingPanel).setClickable(false);
activity.findViewById(R.id.webView).setClickable(true);
}
}
I also tried with requestFocus():
activity.findViewById(R.id.loadingPanel).requestFocus();
And adding listeners to the views:
mWebView.setOnTouchListener(new OnTouchListener() { // declare listener...
Any idea of why is this happening???
Add this attribute to your ProgressBar element in XML:
android:clickable="true"
Change your RelativeLayout (the ProgressBar View parent) attributes to:
<RelativeLayout
android:id="#+id/loadingPanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:layout_centerInParent="true" >
This will make your RelativeLayout to cover your whole layout (not just 100dpx100dp) and to receive the clicks while its visible.
Related
I have fullscreen fragment dialog. While it is showing, background objects can be clickable or interact with user. how do i avoid this?
Here is piece of code how i show dialog:
MainActivity.java
FullScreenFrDialog fr = new FullScreenFrDialog();
FragmentTransaction tr = getSupportFragmentManager().beginTransaction();
tr.add(android.R.id.content, fr, FR_TAG).commit();
FullScreenFrDialog.java
public class FullScreenFrDialog extends DialogFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog, container, false);
return view;
}
}
dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCFFFFFF" >
<ImageView
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
</FrameLayout>
main_activity.xml
<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" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</RelativeLayout>
This button clickable, while dialog is showing.
Thanks in advance.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:background="#CCFFFFFF" >
Make the parents clickable true, hope this will help you.
In your onCreate() simply call setCancelable(false). This will prevent the dialog from closing if tapped outside the dialog and will also prevent tap events to the elements beneath
EDIT
Alternatively you can call setCanceledOnTouchOutside(false) if you want it to be dismissed with a back button press but still prevent touches to elements beneath
I have a TRANSPARENT overlay in my android app that when user click on it,it fade but it can't fill all activity like below image
MainActivity :
<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"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="This is Original View" />
</RelativeLayout>
OverlayActivity :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/over_lay_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#50220000" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:text="This is Overlay View" />
</RelativeLayout>
Java :
public class MainActivity extends Activity {
private ImageView mOverLayImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Dialog overlayInfo = new Dialog(MainActivity.this);
overlayInfo.requestWindowFeature(Window.FEATURE_NO_TITLE);
overlayInfo.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
overlayInfo.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
overlayInfo.setContentView(R.layout.overlay_view);
overlayInfo.show();
mOverLayImage = (ImageView) overlayInfo.findViewById(R.id.over_lay_image);
mOverLayImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
overlayInfo.cancel();
}
});
}
}
Use FrameLayout. Each item added to FrameLayout is on top of the previous one, like in this example the second TextView is on top of the frist one, but since it is not fully opaque, you can see them both!
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:text="Blablabla"
android:background="#FFFFFFFF"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#50220000"
android:textColor="#FFFFFF"
android:text="I am on top"
android:gravity="center"
/>
</FrameLayout>
Now all you need to do is show/hide the overlayed items and you are good to go.
Delete your overlay activity, and inside your main activity apply this code :
<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"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="This is Original View" />
<!-- This is your overlay -->
<RelativeLayout android:id="#+id/over_lay_page"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/over_lay_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#50220000"
android:onClick="clickedOverlay" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:text="This is Overlay View" />
</RelativeLayout>
</RelativeLayout>
Note that I added a line on your ImageView which runs a function when clicked, now on your java file add this function:
//The onClick on xml requires a function of signature void(View) which is the clicked view (in this case the ImageView)
public void clickedOverlay(View view)
{
//ImageView is clicked
RelativeLayout rlLayout = (RelativeLayout) findViewById(R.id.over_lay_page);
rlLayout.setVisibility(View.GONE);
}
This will make the RelativeLayout that contains the overlay views (including the ImageView which is clicked) to not only be invisible but not to interfere with anything. It also ignores input to it.
In case I misunderstood anything about your question feel free to correct me (I'm not sure I understood that completely).
Also if you want it to fade in or out or something like that you can do it with an AlphaAnimation.
So I implemented a Pull-to-Refresh on my GridView using android.support.v4.widget.SwipeRefreshLayout and it works well. But when dragging down the finger, only the animation plays and the 'GridView-being-pulled-down-animation' doesn't happen like it should when refreshing. The GridView stays intact while it gets updated. How can I override this animation method and add a GridView movement which clearly shows the animation where the GridView gets pulled down with the finger's movement? (similar to facebook, instagram's refresh)
And also maybe display a message at the top saying 'Refreshing'
My Code so far.
XML:
<RelativeLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ECECEC"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="#dimen/feed_item_margin"
android:layout_marginRight="#dimen/feed_item_margin"
android:layout_marginTop="#dimen/feed_item_margin"
android:orientation="vertical"
android:paddingBottom="#dimen/feed_item_padding_top_bottom"
android:paddingTop="#dimen/feed_item_padding_top_bottom" >
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<GridView
android:id="#+id/grid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:columnWidth="100dp"
android:gravity="center"
android:numColumns="1"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
</RelativeLayout>
Code:
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(new OnRefreshListener() {
#Override
public void onRefresh() {
//my update process
RequestParams params = new RequestParams();
params.put("req", "dataReqAndroid");
invokeWS(params);
}
});
swipeLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
I have created an Android app with the new ads sdk, but it is invisible. I got it working in a previous app, it works good there. Now, in my new app, I have done the same. But:
The AdView is not visible, but clickable. If you go back to your home screen (just minimize, dont stop!), and re-open it, the ad will be shown.
My XML file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.android.gms.ads"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="vertical" >
<org.andengine.opengl.view.RenderSurfaceView
android:id="#+id/SurfaceViewId"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:gravity="center" />
<com.google.android.gms.ads.AdView xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="#+id/adViewId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
ads:adUnitId="XXX"
ads:adSize="BANNER" />
</RelativeLayout>
And my onCreate method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
adView = (AdView) findViewById(R.id.adViewId);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
}
EDIT: After 60 sec., the view becomes visible.
Your problem is that you have told you RenderSurfaceView to matchParent forits height. THis means that it will consume all of the space of its parent leaving none for the AdView.
Try this instead:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.android.gms.ads"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="vertical" >
<org.andengine.opengl.view.RenderSurfaceView
android:id="#+id/SurfaceViewId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center" />
<com.google.android.gms.ads.AdView xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="#+id/adViewId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
ads:adUnitId="XXX"
ads:adSize="BANNER" />
</LinearLayout>
This uses layout_weight with LinearLayout to have your RenderSurfaceView expand to fill all unused vertical space.
Maybe you forgot implementing these important methods
public void onPause() {
super.onPause();
this.adView.pause();
}
public void onResume() {
super.onResume();
this.adView.resume();
}
Our application makes heavy use of webviews. When testing on ICS, we noticed that we need to set the application property hardwareAccelerated="true". However, doing this caused a few other bugs in our application, most of which we have fixed. We are still having problems getting our 'slide-in' animation working. Without any code changes, the animation simply does a 'reveal' type animation rather than sliding. We have tries a few different things:
Adding a small alpha transition (.99->1). This changes the 'reveal' to a 'slide' but causes some weird artifacts on the screen sometimes.
using hardware layers during the animation. This doesn't work consistently.
using software layers during the animation. This works, but causes a slow redraw after the slide-in animation completes for the first time.
Approach 3 is the most promising, but we have not figured out how to avoid the redraw. We have created a small test case using a sample project with a single activity:
activity class:
int accelValue = View.LAYER_TYPE_NONE; //hack
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
addClickListenerAnimation(R.id.buttonhl, R.anim.to_left, View.VISIBLE, View.INVISIBLE);
addClickListenerAnimation(R.id.buttonhr, R.anim.to_right, View.VISIBLE, View.INVISIBLE);
addClickListenerAnimation(R.id.buttonsl, R.anim.from_left, View.INVISIBLE, View.VISIBLE);
addClickListenerAnimation(R.id.buttonsr, R.anim.from_right, View.INVISIBLE, View.VISIBLE);
final Button b = (Button) findViewById(R.id.accel);
b.setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View v)
{
accelValue = ++accelValue % 3;
b.setText(accelValue == 0 ? "NONE" : accelValue == 1 ? "S/W" : "H/W");
}
});
}
private void addClickListenerAnimation(int buttonId, final int animId, final int startVis, final int endVis)
{
Button b = (Button) findViewById(buttonId);
b.setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View v)
{
final WebView wv = (WebView) findViewById(R.id.webview);
final View layout = findViewById(R.id.frame);
Animation a = AnimationUtils.loadAnimation(getApplicationContext(), animId);
a.setDuration(500);
a.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation)
{
Log.i("sb", "layer type was " + wv.getLayerType());
Log.i("sb", "llayout layer type was " + layout.getLayerType());
wv.setLayerType(accelValue, null);
Log.i("sb", "setting layer type " + accelValue);
}
#Override
public void onAnimationRepeat(Animation animation)
{
}
#Override
public void onAnimationEnd(Animation animation)
{
wv.setLayerType(View.LAYER_TYPE_NONE, null);
Log.i("sb", "restoring layout layer type " + layout.getLayerType());
}
});
layout.setAnimation(a);
layout.setVisibility(endVis);
}
});
}
#Override
protected void onStart()
{
super.onStart();
((WebView)findViewById(R.id.webview)).loadUrl("http://www.wikipedia.org");
}
from_left.xml animation (other animation xmls are similar):
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true">
<translate android:fromXDelta="-100%"
android:toXDelta="0%"
android:fromYDelta="0%"
android:toYDelta="0%"
android:duration="600"
android:zAdjustment="bottom"
/>
</set>
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/frame"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="invisible"
>
<WebView
android:id="#+id/webview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</FrameLayout>
<View
android:layout_width="fill_parent"
android:layout_height="80dp"
android:background="#FF000000" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="80dp"
android:orientation="horizontal" >
<Button
android:id="#+id/buttonsl"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="show L" />
<Button
android:id="#+id/buttonhl"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="hide L" />
<Button
android:id="#+id/buttonsr"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="show R" />
<Button
android:id="#+id/buttonhr"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="hide R" />
<Button
android:id="#+id/accel"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="NONE" />
</LinearLayout>
</LinearLayout>
manifest:
<uses-sdk android:minSdkVersion="14" />
<uses-permission android:name="android.permission.INTERNET" />
Well, if you are trying to support ICS and onward, you can use the new Animation APIs as they are much easier to use and I believe will be very smooth.
Here are two links to take a look into this API:
this and this
And if you want to use this API for older versions, try NineOldAndroids
Edit: Try setting the WebView's Layer to a Software one:
web.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
It stopped the flickering but you lose hardware acceleration inside the view. I am not sure but I guess that for stuff like animation the view would still be considered as having hardware acceleration since its "container" still does. But I could be completely wrong too.
it worked fine for me using
web.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
the flickering issue was solved
From you description it seems like that's the same problem I had, though I'm not completely sure of that. At first I used your solution, but now I have one that works even better. I simply set
android:alwaysDrawnWithCache="true"
on the web view. That get's rid of all flickering and wrong drawing.
I hope it helps!