I'm using ViewPager as my main navigation in app. I'm using ActionBar, as well. What I want to achieve is that when user clicks search button in ActionBar I want to have blurred background. So my approach is to take a screenshot, blur it, set as ImageView and display as an overlay over the whole view. And it works. But problem is that actually when I first open search it displays proper screenshot. Then I turn overlay off, change page in ViewPager, click search again and ... I can see the previous screenshot- not new one with new page on it. Here are my snippets of code:
show and hide overlay on search click (I'm passing R.id.container view which is parent id of my content view, menuOverlay is my ImageView referenced from layout)
Here's my method that takes screenshot and makes it blurry
// Ad. 1
item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem menuItem) {
if(menuItem.getItemId() == R.id.action_search) {
menuOverlay.setImageBitmap(Utils.takeSnapshot(findViewById(R.id.container)));
menuOverlay.setVisibility(View.VISIBLE);
}
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem menuItem) {
if(menuItem.getItemId() == R.id.action_search) {
menuOverlay.setVisibility(View.GONE);
}
return true;
}
});
// Ad. 2
public static Bitmap takeSnapshot(View v) {
v.setDrawingCacheEnabled(true);
v.buildDrawingCache();
Bitmap bm = v.getDrawingCache();
Bitmap scaled = Bitmap.createScaledBitmap(bm, bm.getWidth()/5, bm.getHeight()/5, false);
return Utils.fastblur(scaled, 5);
}
I;m using fast blur algorithm found somewhere here on StackOverflow which is quite fast.
Where's the problem? Why it happens?
ok, I found the answer. if you want to always have "fresh" screenshot you need to destroy cache after all operations:
v.setDrawingCacheEnabled(false);
Related
So in my Flutter project I'm using this plugin flutter_native_screenshot
It works quite well for single screenshot of the page, but it's not taking full scrollable screenshot. I've checked behind this plugin use a code like takeScreenshotOld()
View view = this.activity.getWindow().getDecorView().getRootView();
view.setDrawingCacheEnabled(true);
Bitmap bitmap = null;
if (this.renderer.getClass() == FlutterView.class) {
bitmap = ((FlutterView) this.renderer).getBitmap();
} else if (this.renderer.getClass() == FlutterRenderer.class) {
bitmap = ((FlutterRenderer) this.renderer).getBitmap();
}
The question is:- How can I make this code to take full scrolled screenshot.
I've tried flutter screenshot plugin as well but unfortunately it fails to capture flutter_tex (webview)
and shows blank. The native plugin worked but unable to get full page.
This answer is using Java but you can follow the same logic in flutter,
You will need to do the following steps:
Implement a listener to the scrollView scrolling, then every time the height is dividable by screen height, take a screenshot
Display display = getWindowManager().getDefaultDisplay();
int height = display.getHeight();
mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
int scrollY = targetScrollView.getScrollY();
if (scrollY % height == 0){
takeScreenShotAndSaveIt();
}
}
});
Manullay scroll through the scroll view
mScrollView.post(new Runnable() {
public void run() {
mScrollView.fullScroll(mScrollView.FOCUS_DOWN);
}
});
Finally you will remove scroll listener and merge the saved images of the screen shots.
Another option is to take the full view as bitmap and save it: https://stackoverflow.com/a/43817149/19074651
I have a particular layout which consist a scroll view and an image which is at bottom of the activity. My question is that when I start scrolling up that image will not visible and when the scroll reach to top it is visible again.
I attached my image link so that you get the idea what I want.
You can achieve this easily with android support widget CoordinatorLayout.
Follow this post to hide/show the image based on scrolling.
You can learn more about coordinator layout here
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
if (scrollView != null) {
if (scrollView.getChildAt(0).getBottom() <= (scrollView.getHeight() + scrollView.getScrollY())) {
relativeLayout.setVisibility(View.VISIBLE);
}
else {
relativeLayout.setVisibility(View.INVISIBLE);
}
}
}
});
Here is something that you should try out
ScrollView sv = (ScrollView)findViewById(R.id.scrl);
sv.scrollTo(0, sv.getTop());
and when it gets to top show the visibility of the image view as visible and in else part make it gone...
I am trying to fade two images back and forth:
Image1 with an id of imageone
Image2 with an id of imagetwo
For both the images, I have linked onClick in UI properties to the onClick method in the below Java code.
After the launching the app, when I click on image1, it is supposed to fade out and image2 should fade IN.
After analysis, I determined that the flow is not entering the if statement and is always getting directed to else no matter what.
How can I solve this?
Why is the if statement if (view.getId() == R.id.imageone) not letting the flow inside it even though the entry condition view.getId() == R.id.imageone is true?
public class MainActivity extends AppCompatActivity {
public void onClick(View view) {
ImageView imageone = (ImageView) findViewById(R.id.imageone);
ImageView imagetwo = (ImageView) findViewById(R.id.imagetwo);
if (view.getId() == R.id.imageone) {
imageone.animate().alpha(0f).setDuration(2000);//image1 fade OUT
imagetwo.animate().alpha(1f).setDuration(2000);//image2 fade IN
} else {
imagetwo.animate().alpha(0f).setDuration(2000);//image2 fade OUT
imageone.animate().alpha(1f).setDuration(2000);//image1 fade IN
}
}
}
#Narendra Jadon : You are right ,The problem was with the layout. The image two was on top of image one. And i solved it by setting the image one on top of image 2. Thank you everyone for your help.
I have a Android app that includes a wallpaper picker.
It loads thumbnails into a gallery widget and when one is selected it displays in a large imageview behind the gallery. All in one Activity
All the wallpapers and thumbs are loading from web by a manifest parser and node. They load just fine.
Problem is that when the menu item to save/apply the wallpaper is pressed before the imageview is loaded has issues. If i wait until the imageview loads it no issue.
I tried getting around this by doing the following.
I had the mImageDrawableSet boolean set to false unless the loading was complete
ImageLoader.getInstance().displayImage(mNode.url, mImageView, new ImageLoadingListener() {
#Override
public void onLoadingStarted () {
mImageDrawableSet = false;
mImageView.setVisibility(View.GONE);
mPending.setVisibility(View.VISIBLE);
}
#Override
public void onLoadingFailed (FailReason failReason) {
mImageDrawableSet = false;
Toast.makeText(getActivity(), "Image Failed To Load!", Toast.LENGTH_SHORT).show();
}
#Override
public void onLoadingComplete (Bitmap bitmap) {
mImageDrawableSet = true;
mImageView.setVisibility(View.VISIBLE);
mImageView.setImageBitmap(bitmap);
mImageView.setZoomable(true);
mPending.setVisibility(View.GONE);
if (mApplyImageOnDisplay)
applyImage();
if (mSaveImageOnDisplay)
exportImage();
}
#Override
public void onLoadingCancelled () {
}
});
Then when the exportImage() is called it looks to see if mImageDrawableSet it flase and if it is then it sets mSaveImageOnDisplay to true. So, when the loading is complete above it will call the exportImage() and process beyond what i posted below.
public void exportImage () {
if (this.mImageDrawableSet == false) {
this.mSaveImageOnDisplay = true;
return;
}
try {
final Bitmap bitmap = getImageBitmap();
That example from above was from a code where it showed a single imageview in one fragment. I am now using a Activity where all wallpapers are shown in one imageview depending on which thumbnail is selected.
Also I ditched UIL and am not using Picasso and it doesn't a loading started. just loading failed and complete.
So the only way that i have been able to make this work is create a boolean that is set to false on activity start.
Then on option menu item i have this
if (ReadyBoolean.getValue()){
setProgressBarIndeterminateVisibility(true);
applyCrop();
} else {
Toast.makeText(this, "Please wait until wallpaper loads", Toast.LENGTH_SHORT).show();
}
return true;
On the picasso loading complete i set it to true, then back to false after the save function runs.
So, it works but i hate i have to display a message that say please wait until wallpaper loads. I wish it would just work after the imageview loads. I can't seem to figure out how to do it
I've a ViewPager with an PageAdapter loading ImageViews.
The images displayed come from the internet and I use an AsyncTask for loading the Bitmap and then (if the Page hasn't been destroyed) assign it to the ImageView.
#Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView img = new ImageView(container.getContext());
new LoadImageTask(img,Data.getImageUrL(position)).execute();
container.addView(img );
return img;
}
So the ImageView has two states: loading or loaded. I need to track if the user waits for the image. So I implement this at the LoadImageTask onPostExecute:
if (loadListener != null) {
loadListener.onImageLoaded(position);
}
And in the listener:
public void onImageLoaded(int position) {
if (position == mViewPager.getCurrentItem()) {
// Save record ..
}
}
Since I only need to count the images displayed at the "Current Item of the ViewPager" this method is not enought because if the user moves to the item 5 for example, the ViewPager loads in cache the item 6. If the user waits enought time for this load (beeing the item 5 the current) the callback to onImageLoaded is lost (because the item 6 is not the currentItem at the moment, and then when the user moves to the item 6 I've no way of knowing if the image is loaded or not.
I was thinking in adding something like [[PSEUDOCODE]]:
mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
if (mViewPager.isLoaded(posistion)){
// Save record ...
}
}
But I dont know how to retrieve if the corresponding view loaded the image or not at this moment. How can I do it?