nodpi drawables fail when used from another activity immediately started in onCreate - android

I've been using no-dpi drawables in my application for tiled backgrounds and it works great, but it fails when I start another activity in the onCreate of my main-activity.
This behaviour does not occur in an emulator which leads me to think it's something device-related. I'm using a Samsung Galaxy Note to test this on (Android 2.3.6).
Reproduction
For debugging purposes I've created a new project, added the tile.png to the drawable-nodpi folder, created bg_tile.xml in the drawable folder and set the background in the main.xml layout file to "#drawable/bg_tile"
So far so good:
http://i.stack.imgur.com/FGrr1.png
Now I've copied the main.xml to secondary.xml, and created another activity which uses secondary.xml.
To open the secondary activity, I've added it to the onCreate of the main activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent activityIntent = new Intent(this, NoDPISecondaryActivity.class);
this.startActivity(activityIntent);
}
The secondary activity should be shown with the same tiled background as in the main activity, but instead it scales the drawable:
http://i.stack.imgur.com/9Xwwp.png
What next?
It this just something Samsung related where I've got to learn to live with, or has anyone got a clue on what's going on and how to fix this behaviour?
My observations:
Pressing "back" returns to the main activity which shows the tiled background correctly.
Also, the secondary activity shows correctly when I initiate it using a button with an OnClickListener
Contents of the bg_tile.xml file:
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/tile"
android:tileMode="repeat" />

After updating the Galaxy Note to Android 4.0 this is resolved. Looks like it was a vendor/device-specific bug.

Related

Android : Presenting transparent activity causes crash

Basically, I have an app with two Activities.
#1 - MainActivity
This has a solid black background and a button.
When the button is pressed TransparentActivity should be presented.
#2 - TransparentActivity
I want this to be transparent (so the phones normal UI can be seen through).
I've tried using the following code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(android.R.style.Theme_Translucent);
setContentView(R.layout.activity_trick);
}
But it causes the app to crash with an NullPointerException.
Try1:
Make super.onCreate(savedInstanceState); call after setTheme(android.R.style.Theme_Translucent);. So do as:
setTheme(android.R.style.Theme_Translucent);
super.onCreate(savedInstanceState);
Try 2:
If that doesn't work, I find the following way easiest to make my activity transparent:
<activity android:name=".your.activity.declaration.here"
android:theme="#android:style/Theme.Translucent.NoTitleBar" />
Basically add android:theme="#android:style/Theme.Translucent.NoTitleBar" to your activity declaration in manifest. I can see that you are trying to do a similar thing programatically but by specifying it in manifest never crashed for me. If it does, then there might be other reasons.
Hope it helps.
AppCompatActivity hasn't the Theme_Translucent(maybe the Theme_Translucent is null),you should create your own style.

switching between dialog and activity based on device size

In any application the add/edit will be comparatively having lesser inputs. I have seen that the application, esp., calendar, are using clever strategy to show these as simple dialog, so that the user may not notice that there is empty space in the designed form
As shown below
My question is, how to make it happen?
What I'm doing is I extend DialogFragment:
public class AboutFragment extends DialogFragment { ... }
I also have an activity that contains that fragment. And when the dialog/activity needs to be called, this method decides how to display it:
public static void showAbout(Activity parent) {
if (isTablet) {
AboutFragment aboutFragment = AboutFragment.newInstance();
aboutFragment.setStyle(DialogFragment.STYLE_NORMAL, R.style.DialogTheme);
DialogUtils.showDialog(parent, aboutFragment);
} else {
Intent aboutIntent = new Intent(parent, AboutActivity.class);
parent.startActivity(aboutIntent);
}
}
How to decide whether it is a tablet, is totally up to you.
This technique is explained in the documentation.
In my opinion the best approach here is to use
<!-- Theme for a window without an action bar that will be displayed either full-screen
on smaller screens (small, normal) or as a dialog on larger screens
(large, xlarge). -->
"android:Theme.Holo.Light.DialogWhenLarge.NoActionBar"
The best/easiest solution I've found is to always use an Activity, and based on screensize (and version), change your Theme parent.
in res/values/themes.xml
<style name="Detail.Theme" parent="#android:style/Theme.Holo.Light" >
...
</style>
and in res/values-large/themes.xml
<style name="Detail.Theme" parent="#android:style/Theme.Holo.Light.DialogWhenLarge" >
...
</style>
use Context.setTheme method to set them programmetically. As the doc says
this should be called before any views are instantiated in the Context
(for example before calling.
So, to switch between themes need to call setTheme before onCreate
public void onCreate(Bundle savedInstanceState) {
// check screen size
setTheme(dialogTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
As #StinePike answered, setting a dialog theme programatically doesn't do any use (to me), as it shows a wierd black screen behind the dialog, rather than a dimmed background (as shown in the question). This is obviously a bug.
Instead of trying to set it programatically, or in style.xml, and pretty much everywhere except for AndroidManifest.xml, I did the reverse, which has worked for me.
(the solution which I took from the marvelous solution of the above issue)
The simplest solution (that works) as follows:
1. Make the activity a dialog by default through AndroidManifest.xml:
e.g., in the AndroidManifest.xml:
<activity
android:name="com.example.MyActivity"
android:label="#string/title_activity_mine"
android:theme="#android:style/Theme.DeviceDefault.Dialog">
...
</activity>
2. On starting the activity, set the theme to default if device is not a tablet.
if (!(isTablet(this)) {
setTheme(defaultTheme);
}
super.onCreate(savedInstanceState);
...
Note:
solution will work with custom styles defined in style.xml.
Ref:
How to detect device is Android phone or Android tablet?
Dialog with transparent background in Android
Issue 4394 - android - setTheme() does not work as expected
PS: final app on tablet and phone is as follows:
Use a DailogFragment and then control how its shown with setShowsDialog()

Changing an ImageButton image programmatically

I have successfully set an image to an ImageButton using this code:
mGetClickTime.setImageResource(randomImageId);
But I'm trying to problematically change the image by calling a method which contains:
mGetClickTime.setImageResource(randomImageId);
(In which the randomImageId vraiable is different)
However the programmatic change is not working.
Do I need to remove the current image before setting a new one? If so, how do I do that?
EDIT
The problem seems to be that the above command stops working after another activity has been called and completed. After that happens the setImageResource just doesn't work.
I'm not sure why this could be. I've tried commenting out everything from the second activity apart from this
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
but the problem still occurs. Why?
Give this a try:
mGetClickTime.setBackgroundResource(randomImageId);
This will work in an onClick method. That might be your issue, but not 100% sure until I see the context of the code.

How to structure my android application

I'm very new to Android development, and want to make sure that I'm structuring my application correctly. First, let me explain what is needed.
The application starts off prompting the user for an access code, depending on their response there are two resulting menu's which can appear. One menu has 5 buttons, while the other adds two extra buttons making seven. Each one of those buttons brings me to a different view where more information will be displayed.
I originally starting writing it with one activity and a different XML file for each view. However, the more I have been researching online it seems that I should have a different Activity for each individual view. But now I'm relatively confused how I can prompt the user for input before initializing any of the Activities.
If anyone has any input I'd really appreciate it.
Thanks
You will need to initialize an activity before getting user input. And I think it is common that if you go to a new view that it uses a different class and xml layout. So for each of the new views you could make a new class that extends an activity and then has an xml file related to that view.
So have these 2 files for each new view you show.
Java file:
public class Activity1 extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
}
}
XML file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
//add any views
</LinearLayout>
Try:
-push activity1 with layout1
-pop inputDialog
-when inputDialog is closed by clicking ok...
-push Activity2 with layout2, proceed with you input from activity1 using extras
...and so on ;)
I have been trying to break up my programs into an activity and a corresponding xml layout for each view. If you have one activity and all those layouts, you have the potential to have a monster block of code in that one activity. I find that breaking it up makes it easier to read and debug.
As for prompting the user before initializing activities, i'm not entirely clear on what you mean. You need to load an activity before anything happens, in your situation it could easily be a simple password acception activity. If you're talking about passing information between activities, you can package data in an intent, and use that to start a new activity. Then in that new activity pull the information out of the intent.

Switching Views/layouts

I have a problem that I can't seem to find the solution to.
I have an app that loads the main.xml file on startup, of course. In it are several buttons, and I want the buttons to take me to a different XML file. I just used setContentView(R.layout.newlayout.xml) method for that, and it works great.
The problem comes in after that. If I reference any of the buttons or other objects in the new layout, the app won't even finish loading before it errors out and closes on the emulator. However, if I take all references to objects out, the app runs fine.
I can navigate TO the new layouts, but their buttons can't do anything. Do I need to create a separate Java file for each layout? Or am I doing it all wrong? I'm trying to be as specific as I can. I suppose you could say I need to have different "pages" in my app as a website would.
I think what you are trying to do is best solved using multiple java files, each one defining it's own android Activity.
While it is possible to have multiple layouts/views in a single activity, this will generally make the code more complex and harder to read/debug in the future. By having each 'screen' in its own file, it will be a bit easier to manage all the different views you need to juggle.
The buttons and views only can refer to those mentioned in the current SetContentView() file..
u can test this by creating a button and initialising to an R.id... without setting the content view.. U will get a force close..
so if u change the XML file u shud initialise stuff again....
Ok, for anyone out there with the same problem and haven't figured out how to do it, as I said in my comment on ylebre, my Coworker and I have finally discovered how to do it. First off, we added
implements OnClickListener
to the class, after
extends Activity
then, we created a new java file, and at the beginning of the file it called
setContentView(R.layout.newlayout);
instead of main. Then, we made a button as follows:
Button button1 = (Button) findViewById(R.id.button01;
button1.setOnClickListener(this);
then later in the code:
public void onClick(View v) {
switch(v.getId()) {
case R.id.button01:
startActivity(new Intent(this, NEWJAVAFILE.class));
break;
}
}
And that's it! We just copied and pasted that code into NEWJAVAFILE, changed the names and such, and we were able to navigate freely back and forth. As ylebre said, all of the code for the new activity is in the NEWJAVAFILE.java. OH and don't forget to add the name of the java file to the manifest inside the tags:
<activity android:name=".NEWJAVAFILE">
</activity>
it all seems so simple now!

Categories

Resources