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.
Related
I really didn't want to post it here because this problem sounds really stupid and is difficult to describe, but after hiting my head 2 hours for a stupid layout problem i decided to try
I've one activity with several layout components...
During on create all components are set to be invisible just one keeps visible.
When user presses the button, all components turn visible
when presses button again, all components SHOULD turn invisible again
ALL COMPONENTS VISIBILITY IS ADJUST IN ONLY ONE METHOD
so the activity looks like:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new_giveaway, R.id.mainView);
/*lots of stuff*/
//last thing
makeVisible(View.INVISIBLE);
}
private void makeVisible(int visi) {
findViewById(R.id.cardView).setVisibility(visi);
((ViewGroup) findViewById(R.id.influencerLayout)).setVisibility(visi);
this.recyclerView.setVisibility(visi);
}
the problem: is on second click all components get invisible but one keeps on screen
the component which stays on is a cardview
Mainlayout:
<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="com.tomatedigital.giveawaymaster.activity.NewGiveawayActivity">
//lots of stuff//
<include layout="#layout/giveaway" />
layout/giveaway is:
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="#dimen/giveawayCardHeight"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="4dp"
card_view:cardUseCompatPadding="true">
//lots of other stuf
</cardview>
It's the first thing i set visible on controller method but the only which doesn't go back invisible
REPEATING: there is no other calls to setVisibility other than these, all visibitilities are controled just under that method
I didn't post the whole activity code here because is way long
==========UPDATE==========
Just to clarify:
1- the cardview is one separated layout file re-used several places
2- there is only one cardview in the mainlayout
3
if i remove makeVisible(View.INVISIBLE)from onCreate(), all stuff stays visible,
if i call makeVisible(View.INVISIBLE) and never call makeVisible(View.VISIBLE) all stuff stays invisible
but if I invisble->visible->invisible everything goes invisible but cardview keeps visible
When you want to set the whole layout to Invisibility state, you need to do it in your include #layout/giveaway.xml. Becouse it is a view too.
Like we talk in comments...
Background
I have a rather complex layout being shown to the user in an activity.
One of the views is an EditText.
Since I had to make one of the views stay behind the soft-keyboard, yet the rest above it, I had to listen to view-layout changes (written about it here).
The problem
I've noticed that whenever the EditText has focus and shows its caret, the entire view-hierarchy gets re-layout.
You can see it by either looking at the log of the listener I've created, or by enabling "show surface updates" via the developers settings.
This causes bad performance on some devices, especially if the layout of the activity is complex or have fragments that have complex layouts.
The code
I'm not going to show the original code, but there is a simple way to reproduce the issue:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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="com.example.user.myapplication.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="just some text"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="phone"
android:text="write here"
android:textSize="18dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="just some text 2"/>
</LinearLayout>
</FrameLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(android.R.id.content).getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
#Override
public boolean onPreDraw() {
Log.d("AppLog", "onPreDraw");
return true;
}
});
}
}
What I've tried
When disabling the caret (using "cursorVisible", which for some reason is called a "cursor" instead) , I can see that the problem doesn't exist.
I've tried to find an alternative to the built-in caret behavior, but I can't find. Only thing I've found is this post, but it seems to make it static and I'm not sure as to how well it performs (performance and compatibility vs normal caret).
I've tried to set the size of the EditText forcefully, so that it won't need to cause invalidation of the layout that contains it. It didn't work.
I've also noticed that on the original app, the logs can (for some reason) continue being written even when the app goes to the background.
I've reported about this issue (including sample and video) here, hoping that Google will show what's wrong or a fix for this.
The question
Is there a way to avoid the re-layout of the entire view hierarchy ? A way that will still let the EditText have the same look&feel of normal EditText?
Maybe a way to customize how the EditText behaves with the caret?
I've noticed that whenever the EditText has focus and shows its caret,
the entire view-hierarchy gets re-layout.
This is not true. Size and position of EditText is constant - there is no re-layouting. You can check it by using code below.
findViewById(android.R.id.content).getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Log.d("AppLog", "Layout phase");
}
});
Because of blinking caret - EditText constatly calls invalidate(). This forces the GPU to draw EditText again.
On my nexus 5 (marshmallow) I see that only EditText beeing redrawn (Show GPU view updates - enabled).
How about overriding dispatchOnPreDraw() all the vies you use in activity and having flag to check whether that specific view needs to redraw ?
As you need to disable redraw of all other views only when a text view is on focus. So when a text view is on focus have a flag to disable the redrawing of other views.
if dispatchOnPreDraw() method returns false then refreshing of view will be continues else not. I don't know how complex is your layout and how many views are used, but here a separate class should extent a view used and override that method, and also need a mechanism/variable to distinguish the object in current focus.
Hope this method helps!
I have a TextView in my application that works fine until I pause the application (by pressing home) and launch it again. It should just resume the activity, but for some reason the TextView doesn't display the text properly after it resumes the activity. The text is showing up as black squares, like this:
http://i.stack.imgur.com/5mtvy.png
Does anyone know how to fix this?
EDIT: Here's my code:
The TextView is created in a layout xml that has a GLSurfaceView (called GameView) and on top of that a TextView. Here's the xml 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" >
<GameView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/gv"
/>
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:textColor="#android:color/black"
android:id="#+id/tv" />
</RelativeLayout>
And here is the code in the MainActivity class onCreate method:
setContentView(R.layout.activity_main);
GameView gameView = (GameView) findViewById(R.id.gv);
TextView textView = (TextView) findViewById(R.id.tv);
The onPause, onResume, onStart, onStop methods have nothing related to the TextView.
The TextView is saved into an instance variable for MainActivity and later, TextView.setText() is called to set the text of the TextView.
EDIT: I was able to fix this problem by commenting out one line: GLES20.glDeleteTextures(...) that was being called onPause() I have NO idea how this is even related or why calling this function caused that issue, but when I comment it out the problem goes away and when I bring this line back the problem comes back with it. If anyone can explain how one relates to the other, it would be greatly appreciated.
Check what u have in on start and on stop methods, it is for sure painting what u have typed earlier.
Try putting
#Override
public void onResume() {
super.onResume(); // Always call the superclass method first
TextView textView = (TextView) findViewById(R.id.tv);
textView.forceLayout();
}
Let me know if this solves your problem or not?
I encountered the same situation.
Just make sure your deleting view(which uses opengl) texture action in the thread you created it.
In your case, GameView is the key.
I am facing a quite interesting but annoying error, in my linear layout i have hided another linear layout using margin in negative and when user selects a type from a list i bring layout to front using Translational Animation the error is that the layout comes to front have an edit text which becomes dead and when i scroll (my main layout is surrounded by scroll view) it comes alive and when i stop scrolling it becomes dead again... i really failed to judge why is this happening so guys plz help....
i have also pasted link of video below showing this annoying behavior of my app
http://www.dailymotion.com/video/xlskk8_android-app-edit-text-error_tech
my layout xml inside scroll view is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:layout_marginTop="-110dip"
android:layout_marginBottom="5dip"
android:id="#+id/notes_editor"
android:orientation="vertical"
>
<EditText
android:id="#+id/enter_note"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:maxLines="2"
android:lines="2">
</EditText>
<Button
android:id="#+id/save_note"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Save" />
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-10dip"
android:id="#+id/notes_list"
android:orientation="vertical"
>
</LinearLayout>
</LinearLayout>
the empty linear layout below button is used for dynamically adding child views all other things are performing their functionality properly, only the edit text showing this abnormal behavior.
the code used for animation is below
public void animateEditor()
{
slider = new TranslateAnimation(0, 0, 0,180 );
slider.setDuration(1250);
slider.setFillAfter(true);
notes_list.startAnimation(slider);
notes_editor.startAnimation(slider);
}
The problem here was when applying slider.setFillAfter(true); the code animates the image of Views but not the actual Views that's why when I see them after sliding down animation they were (EditText and save button) stuck or you can say dead and not listening to their events because actual Views were there behind the layout and at front it was just their image
The solution I found for that problem is to apply following code:
slider.setFillAfter(false);
slider.setFillBefore(false);
// OR you can directly write
slider.setFillEnabled(false);
And then to show actual views on the new place by setting animation listener and using the following method:
public void onAnimationEnd(Animation a)
Placing the views to new position at the end of animation by using above method. And here still comes another problem of blinking which is due to the problem in android animation listener method which is that it is get called before actually animation ends and causes blinking effect, a tricky solution to it is by putting following line of code at first line of public void onAnimationEnd(Animation a) method.
// in my case animation applied to notes_editor so the code will be
notes_editor.clearAnimation();
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.