I'm building an Android application that will be like an eBook. Standard flip through pages, view images, etc. One of the requirements is that in multiple places you will see a preview of what a page will look like. It'll be the exact contents of that page, just in a smaller size.
I can't for the life of me get this preview working the way I need it to. I coded an activity which will display either controls to play audio or video depending on some values passed in the extras. That works fine. The preview should be this activity, but only in a smaller size, and shown in a separate activity. Here's what I've tried to get a smaller version of the activity to show:
First, I stumbled across the poorly documented ActivityGroup object. I figured I could use this to call the activity, and then get the view and throw it into a parent view somehow. Here's what that code looked like:
public class GroupTest extends ActivityGroup {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grouptest);
LocalActivityManager manager = getLocalActivityManager();
Intent intent = new Intent();
intent.setClass(getBaseContext(), ViewElement.class);
intent.putExtra("ElementID", 22);
intent.putExtra("PackID", 10);
Window w = manager.startActivity("videoelement", intent);
View v = w.getDecorView();
// Grab the table and add a view to it.
TableLayout tl = (TableLayout)findViewById(R.id.tlTest);
TableRow tr = new TableRow(this);
tr.addView(v);
tl.addView(tr);
}
}
And here's what the layout looked liked:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="1"
android:id="#+id/tlTest">
</TableLayout>
This sort of worked. The activity ViewElement was indeed displaying in the GroupTest activity. The problem was that whenever I tried to add something else to the table (like a label), the ViewElement activity would disappear. I tinkered with this for a while figuring I was failing to grasp some UI constraint, then realized that the ViewElement activity being displayed had clickable buttons, which isn't what I really want. I just want to see what that page looks like, not be able to interact with it.
So I tried a different approach. Found this page on saving a view to an image: http://jtribe.blogspot.com/2008/12/saving-view-as-image-with-android.html. Sounded more like what I want.
My modified code now looks like:
public class GroupTest extends ActivityGroup {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tocrow);
LocalActivityManager manager = getLocalActivityManager();
Intent intent = new Intent();
intent.setClass(getBaseContext(), ViewElement.class);
intent.putExtra("ElementID", 22);
intent.putExtra("PackID", 10);
Window w = manager.startActivity("videoelement", intent);
View v = w.getDecorView();
Bitmap image = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.RGB_565);
v.draw(new Canvas(image));
ImageView img = (ImageView)findViewById(R.id.ivwElementPreview);
img.setImageBitmap(image);
}
}
And the layout (this is the actual layout I would be putting the previews in if I could get it working):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dip">
<ImageView
android:id="#+id/ivwElementPreview"
android:layout_width="75px"
android:layout_height="75px"
android:layout_marginRight="6dip"
android:src="#drawable/icon" />
<LinearLayout
android:orientation="vertical"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="fill_parent">
<TextView
android:id="#+id/txtElementTitle"
android:layout_width="300px"
android:layout_height="0dip"
android:layout_weight="1"
/>
<ImageView
android:id="#+id/ivwPackIcon"
android:layout_width="15px"
android:layout_height="15px"
android:layout_marginRight="6dip"
android:src="#drawable/icon" />
<ImageView
android:id="#+id/ivwPackIcon"
android:layout_width="15px"
android:layout_height="15px"
android:layout_marginRight="6dip"
android:src="#drawable/icon" />
<TextView
android:id="#+id/txtElementComments"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
/>
</LinearLayout>
</LinearLayout>
This just flat out doesn't work at all. As far as I can tell calling w.getDecorView() doesn't return a view that actually has any height, width, or drawn properties on it. If I run that code I get the error "width and height must be > 0" And if I put in values for width and height, nothing shows but a black image. So I then proceeded to create simple things such as a TextView and draw it to the bitmap to display in my LinearLayout, but could never get it working right either. I'm to the point of just being completely fed up with manipulating UI in Android.
So, has anyone else does something similar with previewing what another activity would look like, and how did you accomplish it? Am I just going down the completely wrong path here? I've googled all over the place and part of me feels like someone has to have solved this problem before, but I've lost over a day of work on it and I just can't pour much more time into it right now.
Thanks for any help.
You have to wait until the view is rendered on screen, then you can ask it to paint itself on any canvas. If the view is not showing on screen it will create an empty, 0x0 image.
If I am getting correctly, you want to place a thumbnail on your activity that is actually the preview of the activity that will be opened when this thumbnail ImageView will be clicked.
The very first time you can have a default image representing the Activity.
Next time, that is after you open this activity, you can obtain the screen shot of your activity:
Take a screenshot of a whole View
Make a thumbnail, and replace the previous thumbnail with this.
Related
I have a collapsing toolbar with ImageView inside, when the image is clicked I want to enlarge it with an animation and go to another "activity" like whatsapp, telegram and a lot of other apps which allow user to click the profile photo of friends.
This will allow the user to see the image in the center of the screen and save or share the picture.
I had a look of Zooming a View http://developer.android.com/training/animation/zoom.html but it isn't enough and I have lag during the animation. (I used the same code provided)
I think your key is shared element transition. You can follow this tutorial
Give the same transition name to both of the views which are in different activities.
android:transitionName="#string/transition_string"
Add this bundle where you start the zoomed activity
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(context, view, view.getTransitionName()).toBundle();
startActivity(intent,bundle);
And don't forget to add this line to your activity's style
<!-- Add this line -->
<item name="android:windowContentTransitions">true</item>
You may want to look at Google's documentation on zooming a view here
Basically the way they tell you to go about this is by creating an imagebutton that will display the smaller image, that when clicked will play an animation, and at the end reveal an imageview with the full sized image in it.
The layout they give as an example is this:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<ImageButton
android:id="#+id/thumb_button_1"
android:layout_width="100dp"
android:layout_height="75dp"
android:layout_marginRight="1dp"
android:src="#drawable/thumb1"
android:scaleType="centerCrop"
android:contentDescription="#string/description_image_1" />
</LinearLayout>
<!-- This initially-hidden ImageView will hold the expanded/zoomed version of
the images above. Without transformations applied, it takes up the entire
screen. To achieve the "zoom" animation, this view's bounds are animated
from the bounds of the thumbnail button above, to its final laid-out
bounds.
-->
<ImageView
android:id="#+id/expanded_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible"
android:contentDescription="#string/description_zoom_touch_close" /></FrameLayout>
Then you can set up the animation like this:
public class ZoomActivity extends FragmentActivity {
// Hold a reference to the current animator,
// so that it can be canceled mid-way.
private Animator mCurrentAnimator;
// The system "short" animation time duration, in milliseconds. This
// duration is ideal for subtle animations or animations that occur
// very frequently.
private int mShortAnimationDuration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zoom);
// Hook up clicks on the thumbnail views.
final View thumb1View = findViewById(R.id.thumb_button_1);
thumb1View.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
zoomImageFromThumb(thumb1View, R.drawable.image1);
}
});
// Retrieve and cache the system's default "short" animation time.
mShortAnimationDuration = getResources().getInteger(
android.R.integer.config_shortAnimTime);
}}
There are several more steps, but at this point I'm literally copy and pasting from their documentation. You really should go read up on it. If you have any questions let me know!
I am all for reusing views in listview. I always set visibility, contents, witdth etc. of all controls again in getView Unfortunately it seems ListView fails to recalculate height.
Picture one shows the initial item showed:
Picture two shows how item one is rendered after we scrolled away and back into it
The background linearlayout height (the black area) made me think that in picture two, Android is reusing a view that just showed a much heigher item (e.g. the second item). But why does it not recalibrate/reset/recalclulate itself (it is in "wrap_content" mode in its XML) when reused as view for the first item which content (text + image) is not as heigh?
In truth I am not sure what is happening. The problem only manifests itself if I have image in the view. I have tried organize the bitmap/image loading in different ways (sample code underneath) with different things commented out, but that does not seem to make much difference. I am really at a loss here as to the reason.
override_listitem_news.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip"
android:background="#android:color/black"
>
<TextView
android:id="#+id/listitem_news_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="22sp"
android:padding="5dip"
android:text="#string/newsItemTitle"/>
<TextView
android:id="#+id/listitem_news_date"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="italic"
android:textSize="15sp"
android:padding="5dip"
android:text="#string/newsItemDate"/>
<TextView
android:id="#+id/listitem_news_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="normal"
android:textSize="15sp"
android:padding="5dip"
android:autoLink="web"
android:text="#string/newsItemDesc"
android:background="#android:color/darker_gray"
/>
<ImageView
android:id="#+id/listitem_news_icon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
Here is code where I load image in getView
ViewTreeObserver vto = image.getViewTreeObserver();
vto.addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
image.getViewTreeObserver().removeGlobalOnLayoutListener(this);
image.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
SharedCode.sharedUtilScaleImage_Width(image);
}
}
);
image.setTag(data.image_file_name + data.image_file_url);
Bitmap bit = null;
bit = SharedCode.sharedGetFileFromOffline(thisActivityContext, "news", data.image_file_name, MyGetKindOfFile.ImageAsBitmap).bitmap;
if (bit != null) {
image.setImageBitmap(bit);
image.setVisibility(View.VISIBLE);
}
else {
image.setImageBitmap(null);
image.setVisibility(View.GONE);
}
image.setPadding(0, 0, 0, 0);
image.setBackgroundColor(data.backgroundColorInt);
For what it is worth, problem appeared to be related to the imageview. Just for reference, I will write here how I solved it.
In getView I fixed the imageview width to screen width (instead of "wrap-content" and/or parent view width - earlier code used OnGlobalLayoutListener for parent width)
I switched over to using SetDrawable instead of SetImageBitmap. It is odd, but this difference was actual very important in solving the odd space around the imageview after scrolling an item/row in/out of view.
My research did also indicate that others had problems using wrap_content in listview for cases similar to mine, but I was not able to find anyone who had experienced exact same problems as me.
I'm developing an app with SupportMapFragment and custom view switching mechanism. Right now i styles app, to make its window to be transparent using styles.xml, but with that change i see a strange problem when using maps. When user switches it current view from one that uses map fragment to another, part of screen that was used by map on previous view becames transparent, for about 1 second.
In image below i present some description, on right i marked using yellow color situation than im talking about:
on left side is view that i present map using SupportMapFragment, on the right is one i have switched next, with 2 diffrent views(ImageView and TextView),but yellow part of TextView is transparent like my application window, su user can notice eg. apps menu. This is not what im trying to achive so Im looking way to get rid of this effect.
My code for switching views is like follows:
public void switchAppView(View view){
mMainView.removeViewAt(0);
mMainView.addView(view,0);
}
the mMainView is initialized in onCreate Method, by code:
#Override
public void onCreate(Bundle icicle){
super.onCreate(icicle);
setContentView(R.layout.activity_main);
mMainView = (RelativeLayout) findViewById(R.id.mymain_layout);
}
my activity_main.xml layout presents similar to:
<RelativeLayout
android:id="#+id/mymain_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<FrameLayout
android:id="#+id/replacable"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="visible"
></FrameLayout>
<FrameLayout
android:id="#+id/extra"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="invisible"
></FrameLayout>
</RelativeLayout>
I tried to search clues and situations like that but I didnt find any, so if anyone can help i would be grateful, Thanks for help.
becames transparent, for about 1 second.
I'm guessing you are using black background and you really mean it becomes black.
In that case what you see is a known issue.
You may read more about it here:
http://code.google.com/p/gmaps-api-issues/issues/detail?id=4659
and here:
http://code.google.com/p/gmaps-api-issues/issues/detail?id=4639
I want to display an image preview over my app: when user presses an item in the listview (each item is a path to an image stored in sd card) image preview appears,stretched in the available space, like in this picture (image space is black, underlying app, still partially visible, is gray):
when user presses back image disappear.
I thought to make an activity just for image displaying but I don't know how to obtain the result in the picture...
Edit:
Ok here's what I've done so far:
1)Manifest:
<activity
android:name=".ImageDialogActivity" android:theme="#android:style/Theme.Dialog">
</activity>
2)Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
3)Activity onCreate method:
super.onCreate(savedInstanceState);
setContentView(R.layout.image_preview);
String filepath = getIntent().getStringExtra("image_filepath");
((ImageView)findViewById(R.id.imageView)).setImageBitmap(getBitmap(filepath));
where getBitmap is a private method which gives me a bitmap from a filepath.
Problem is that I don't have control over dialog dimensions: dialog's width and height seem to depend on contained image ones...not to mention top/right/left/bottom margins...
Solved (maybe):
I modified layout file this way:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="200dp"
>
<ImageView android:id="#+id/imageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerInside"/>
Setting width/height to a square allowed to obtain the effect...my question is: will it work for every phone?Or it is right just for mine?
Your best shot is to display your image in a Dialog
If you then want more control over the display, theme it
If you want to do this by creating a new Activity, you should set its layout parameters to wrap_content so it will appears above the other activity but not fitting the screen totally. Also by setting its theme as Theme.Dialog or an inherited theme, you 2nd activity will be a little bit darker and your activity will appear like a dialog.
You should also try to put layout parameter to fill_parent and add margins if you want the exact result as you shown (don't know if this solution could work).
this is from api demos creating an activit like a dilog try this
public class DialogActivity extends Activity {
/**
* Initialization of the Activity after it is first created. Must at least
* call {#link android.app.Activity#setContentView setContentView()} to
* describe what is to be displayed in the screen.
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
// Be sure to call the super class.
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_LEFT_ICON);
// See assets/res/any/layout/dialog_activity.xml for this
// view layout definition, which is being set here as
// the content of our screen.
setContentView(R.layout.dialog_activity);
getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
android.R.drawable.ic_dialog_alert);
}
}
Solved, solution entered in main post seems working fine!
Im having a few issues with a game that Im making
First of, im making a Tower Defence game and, has you probably know, in a Tower Defence game, the "Monsters" in the game changing their routes every time you block them with a Turret.
Now, the main idea is that when you build a turret the monsters will recalculate their route. The route is calculated like this: before the monster is created it gets a Trail object that gets a direction, a starting point and an ending.
The Trail has an X and Y that increases every call and checks if a turret is located in that coordinates. If a turret is located, the Trail creates 2 new Trail objects, gets the correct one and adds it to himself, that creates a recursive object.
Now I dont know how to write all of this in Java, and if I go with this method, that it will take alot of resources (I think).
The second problem that I have is about drawing a layout over a SurfaceView.
I made a pause button, and when im clicking it the main Thread (the one that draws the game) is supposed to be stopped. Now when the thread is stopped the pause screen should be visible, but the problem is, that if the thread stops, any touch on the screen wouldn't be detected. So I tried to create a RelativeLayout, add to it the Surface and inflate the pause.xml file that containes a FrameLayout with 2 buttons: Resume and Quit, and when the pause button is clicked the FrameLayout should be visible but thats not working.
(I tried again with RelativeLayour instead, but that didn't work either)
Thanks, and if you didn't understanded something please tell me and I will try to be more understandable.
EDIT - THE CODE
pause.xml
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pauseContent"
android:background="#AA000000"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:visibility="invisible">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<Button
android:id="#+id/resume"
android:layout_width="100px"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Resume" />
<Button
android:id="#+id/quit"
android:layout_width="100px"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#id/resume"
android:text="Quit" />
</RelativeLayout>
</RelativeLayout>
GameActivity.java
public class GameActivity extends Activity {
private RelativeLayout mainLayout;
private GameView gameView;
private RelativeLayout pauseContent;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainLayout=new RelativeLayout(this);
LayoutInflater inflater=(LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View v=inflater.inflate(R.layout.pause, null);
pauseContent=(RelativeLayout) v.findViewById(R.id.pauseContent);
gameView=new GameView(GameActivity.this, getWindowManager().getDefaultDisplay().getWidth(), getWindowManager().getDefaultDisplay().getHeight());
mainLayout.addView(gameView);
mainLayout.addView(pauseContent, new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
setContentView(mainLayout);
}
}
(I deleted some of the code that wasn't needed to be shown)
In my game I created a Button object that works like the android UI Button (with the click listener...), now, I created the pause button that when he will be clicked, the pause layout should be visible - that doesn't works.