Why are the layout parm's specified in a layouts XML file not used when you inflate the layout manually in Java. This is a view that is being added to another view.
I have to manually create the layout parms using something like the following after inflating
and before adding to the parent view.
LayoutParams lp = new LayoutParams(-1,-2);
inflatedView.setLayoutParams(lp);
Is there a way to make the newly created view adhere to what is in the XML. I really
hate doing this in Java and divorcing it from the layout's definition.
TIA!
use the LayoutInflater service
Code:
// getSystemService is a method for context and can be called directly from an activity
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
myView = inflater.inflate(R.layout.my_layout, null);
Even better, use the
Code:
inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)
variant with the future parent of the inflated view (with attachToRoot set to false if needed, as required for ListViews) to properly inherit LayoutParams from the parent.
And I simply use LayoutInflater.from(Context) instead of getSystemService(), makes it easy to chain the call :
Code:
LayoutInflater.from(context).inflater(R.layout.my_layout, parent, false);
seydhe said:
Even better, use the
Code:
inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)
variant with the future parent of the inflated view (with attachToRoot set to false if needed, as required for ListViews) to properly inherit LayoutParams from the parent.
And I simply use LayoutInflater.from(Context) instead of getSystemService(), makes it easy to chain the call :
Code:
LayoutInflater.from(context).inflater(R.layout.my_layout, parent, false);
Click to expand...
Click to collapse
I'm not a fan of chaining calls but that's a style thing. I don't really like the readability/debugability/maintainability of them down the line. But again that's just a subjective opinion, to each their own.
And of course what you posted is pretty readable. But I don't think you really meant to pass an int to the XMLPullParser?
Also why do the API docs say this then...
http://developer.android.com/reference/android/view/LayoutInflater.html
This class is used to instantiate layout XML file into its corresponding View objects. It is never be used directly -- use getLayoutInflater() or getSystemService(String) to retrieve a standard LayoutInflater instance that is already hooked up to the current context and correctly configured for the device you are running on. For example:
Code:
LayoutInflater inflater = (LayoutInflater)context.getSystemService
Context.LAYOUT_INFLATER_SERVICE);
Click to expand...
Click to collapse
Is there some danger to using the static LayoutInflater.from(context) ? Or just a badly worded api that is telling us not to instantiate the LayoutInflater ourselves? (I'm guessing the latter).
I have created a custon UI menu, and for backwards compatabilty to non-touchscreen devices (such as google TV) I want the user to be able to visually see that the image is selected (I have tried with my desires trackball and it works but just looks the same)
How would i get my app to show the different image on focus and switch back when off focus?
So far i have tried:
Code:
@Override
public void onFocusChange(View arg0, boolean arg1) {
ImageView imageView = (ImageView) findViewById(R.id.tl);
Drawable newFocusImage;
newFocusImage = getResources().getDrawable(R.drawable.menu_top_left_trans_ic_fcs);
imageView.setImageDrawable(newFocusImage);
}
However this somehow changes it to a completely different image than the new drawable specified, and does not revert on un-focus.
All help would be greatly appreciated
Thanks
Rather than draw a new image, why not say change the alpha channel values to make it appear lighter or darker? Or overlay it with a solid color image with a low alpha value?
The alpha change is a good idea. As a photographer i would say adding a transparent vignette would look great. If you don't know what a vignette is, its basically darkening the edges of an image / a circular gradient (dark edges, light middle)
From something awesome
ye that sounds cool
however my main problem still lies in the coding of the problem, do you know how to code a vignette? is it possible to change a image like that in java?
Instead of using getDrawable and setImageDrawable use setImageResource
Create two images:
menu_top_left_trans_ic_fcs_normal - to be shown when not focused
menu_top_left_trans_ic_fcs_focused - to be shown when focused
Then add to res/drawable a new file named menu_top_left_trans_ic_fcs.xml with the following content:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/menu_top_left_trans_ic_fcs_focused" android:state_focused="true" />
<item android:drawable="@drawable/menu_top_left_trans_ic_fcs_normal" />
</selector>
Note: You can also set android:state_pressed
Use in your code
Code:
imageView.setImageResource(R.drawable.menu_top_left_trans_ic_fcs);
I never tested this exact code but it should work.
thanks it worked !!
I would like to change the font size options that come with the Nook Reader.
The reader.apk comes with seven different font sizes : from 7.0 to 27.0
The smaller at 7.0 is too small to be useful
and the largest at 27.0 is too large
and the jump from the fifth size (13.0) to the sixth size (20) is too big a jump.
I have used apktool to take apart the apk as in this post http://forum.xda-developers.com/showthread.php?t=1735858
The font size options appear to be set in /com/bn/nook/reader/commonui/ReaderCommonUIConstants.smali
lines 117 to 129
I changed the font sizes to 11.0, 12.0, 14.0, 16.0, 18.0, 20.0 and 22.0.
Saved the .smali file.
I then used apktool to put it all back into a newreader.apk
signed newreader.apk
deleted the existing reader.apk from my nook
adb pushed this apk to /system/app/reader.apk
But when I open a book, the font size options are just the same as before my changes. It is as if no changes were made at all
Any suggestions?
ladykayaker said:
I would like to change the font size options that come with the Nook Reader.
The font size options appear to be set in /com/bn/nook/reader/commonui/ReaderCommonUIConstants.smali
lines 117 to 129
Click to expand...
Click to collapse
For those who don't feel like taking apart the apk, the lines referenced are:
Code:
.field public static final FONT_SIZE_1:D = 7.0
.field public static final FONT_SIZE_2:D = 8.5
.field public static final FONT_SIZE_3:D = 9.75
.field public static final FONT_SIZE_4:D = 11.0
.field public static final FONT_SIZE_5:D = 13.0
.field public static final FONT_SIZE_6:D = 20.0
.field public static final FONT_SIZE_7:D = 27.0
Which looks like a pretty reasonable place to make the changes, right?
To understand why this doesn't work, you need to know a little bit more about the Java compiler, specifically what it means to declare a value as static final.
Consider the following Java code:
Code:
private static final double TEST = 9.75;
private static void test() {
double myVal;
myVal = 1.23;
if (myVal != TEST)
myVal = TEST;
}
Since you've flagged the TEST value as static final, you're making a promise to the compiler. And that promise is: "I promise to never, ever change the value of TEST. It's 9.75 now and it's going to be 9.75 every time you run this program no matter what."
When the compiler hears you make that promise, it's just going to go ahead and substitute the value 9.75 every single time it comes across a reference to TEST.
So, to the compiler, the above code "pre-compiles" to:
Code:
private static final double TEST = 9.75;
private static void test() {
double myVal;
myVal = 1.23;
if (myVal != 9.75)
myVal = 9.75;
}
which we can verify against the resulting smali code:
Code:
# static fields
.field private static final TEST:D = 9.75
.method private static test()V
.registers 4
.prologue
.line 6
const-wide v0, 0x3ff3ae147ae147aeL
.line 8
.local v0, myVal:D
const-wide v2, 0x4023800000000000L
cmpl-double v2, v0, v2
if-eqz v2, :cond_13
.line 9
const-wide v0, 0x4023800000000000L
.line 10
:cond_13
return-void
.end method
(0x4023800000000000L is the hexadecimal representation of the double value 9.75)
Notice that there is still a static definition of TEST as 9.75. But in the code, there are no more references to TEST, just references to the value of TEST at the time the code was compiled.
In this example, if you were trying to replace 9.75 with 12.0, you would need to find the value 0x4023800000000000L and replace it with 0x4023800000000000L each place in the code. Of course, you need to be careful: since the constant labels have been stripped, you have no way of knowing if the original code referenced TEST, or 9.75 or OTHER_DEFINITION that also happened to be 9.75 and you don't want to change it in places where it may be referring to 9.75 as the price of a book instead of 9.75 as the size of a font.
Fortunately, 9.75 is a pretty unique value so a quick search through the Reader code results in only one result:
Code:
D:\nook\Reader>grep -ir 0x4023800000000000 *
smali/com/bn/nook/reader/commonui/ReaderCommonUIConstants$5.smali: const-wide v1, 0x4023800000000000L
Looking at the file, we can see in the Init() function is basically preparing a hashmap with the following values
Code:
1 => 0x401c (7.0)
2 => 0x4021 (9.0)
3 => 0x4023800000000000L (9.75)
4 => 0x4026 (11.0)
5 => 0x402a (13.0)
6 => 0x4034 (20.0)
7 => 0x403b (27.0)
Which is funny, because it's actually using 9.0 instead of 8.5 as the second font size despite the defined value and all of the values except 9.75 are defined as integers rather than Doubles. It looks like some B&N programmer ignored the FONT_SIZE_X definitions and just hard coded the values herself. Anyhow, this creates that mapping that is (most likely) used internally by the reader to find the proper sizing to use for each of the 7 font size options.
I don't have Reader.apk installed on my Nook so I can't actually test this out. But I'm pretty sure if you change the values in ReaderCommonUIConstants$5.smali you'll end up with the results you want.
If that doesn't work, let me make a plug for Cool Reader, which among many other advantages versus the stock Reader has a much larger range of font sizes to choose from.
Yes, that did it. I didn't consider that the values would actually be hard-coded!
I have found a Gallery App on GitHub (https://github.com/sevenler/Android_Gallery2D_Custom) that I have integrated into my own app.
Currently the gallery displays all images from my device. What I would like to have is that it ONLY display the images starting at the folder on my sdcard that I specify such as..
private static String targetPath = Environment.getExternalStorageDirectory().toString() + "/DCIM/_private/.nomedia";
I tried several different modifications but I am really struggling.
I was hoping someone could take a look at the source code for the Gallery App on GitHub and tell me how to change it so it does not scan my entire device.
Thanks in advance!!
-Steve
StEVO_M said:
I have found a Gallery App on GitHub (https://github.com/sevenler/Android_Gallery2D_Custom) that I have integrated into my own app.
Currently the gallery displays all images from my device. What I would like to have is that it ONLY display the images starting at the folder on my sdcard that I specify such as..
private static String targetPath = Environment.getExternalStorageDirectory().toString() + "/DCIM/_private/.nomedia";
I tried several different modifications but I am really struggling.
I was hoping someone could take a look at the source code for the Gallery App on GitHub and tell me how to change it so it does not scan my entire device.
Thanks in advance!!
-Steve
Click to expand...
Click to collapse
I had a look at the source and from my understanding the important class here is that DataManager class here. Especially the getTopSetPath() with the static final Strings and maybe the mapMediaItems() methods seem to be where you need to look at. You might have to play around a bit, but this is where I would start.
SimplicityApks said:
I had a look at the source and from my understanding the important class here is that DataManager class here. Especially the getTopSetPath() with the static final Strings and maybe the mapMediaItems() methods seem to be where you need to look at. You might have to play around a bit, but this is where I would start.
Click to expand...
Click to collapse
I have tried adding/changing the following
Added...
//Setting Folder Path
public static final String targetPath = Environment.getExternalStorageDirectory().toString() + "/DCIM/_private/.nomedia";
Changed...
// This is the path for the media set seen by the user at top level.
private static final String TOP_SET_PATH = targetPath;
private static final String TOP_IMAGE_SET_PATH = "/combo/{/mtp,/local/image,/picasa/image}";
private static final String TOP_VIDEO_SET_PATH = "/combo/{/local/video,/picasa/video}";
private static final String TOP_LOCAL_SET_PATH = "/local/all";
private static final String TOP_LOCAL_IMAGE_SET_PATH = "/local/image";
private static final String TOP_LOCAL_VIDEO_SET_PATH = "/local/video";
I even tried setting all of the _PATH s to my targetPath
And I get a NullPointerException
12-13 11:07:47.881: E/AndroidRuntime(23029): Caused by: java.lang.NullPointerException
12-13 11:07:47.881: E/AndroidRuntime(23029): at com.myprivgallery.common.Utils.checkNotNull(Utils.java:48)
Which leads me to this in Utils.java
line 46 // Throws NullPointerException if the input is null.
line 47 public static <T> T checkNotNull(T object) {
line 48 if (object == null) throw new NullPointerException();
line 49 return object;
line 50 }
So if I am reading correctly, it is saying the path is empty. But I know that path works in other apps and it is not empty.
StEVO_M said:
I have tried adding/changing the following
Added...
//Setting Folder Path
public static final String targetPath = Environment.getExternalStorageDirectory().toString() + "/DCIM/_private/.nomedia";
Changed...
// This is the path for the media set seen by the user at top level.
private static final String TOP_SET_PATH = targetPath;
private static final String TOP_IMAGE_SET_PATH = "/combo/{/mtp,/local/image,/picasa/image}";
private static final String TOP_VIDEO_SET_PATH = "/combo/{/local/video,/picasa/video}";
private static final String TOP_LOCAL_SET_PATH = "/local/all";
private static final String TOP_LOCAL_IMAGE_SET_PATH = "/local/image";
private static final String TOP_LOCAL_VIDEO_SET_PATH = "/local/video";
I even tried setting all of the _PATH s to my targetPath
And I get a NullPointerException
12-13 11:07:47.881: E/AndroidRuntime(23029): Caused by: java.lang.NullPointerException
12-13 11:07:47.881: E/AndroidRuntime(23029): at com.myprivgallery.common.Utils.checkNotNull(Utils.java:48)
Which leads me to this in Utils.java
line 46 // Throws NullPointerException if the input is null.
line 47 public static <T> T checkNotNull(T object) {
line 48 if (object == null) throw new NullPointerException();
line 49 return object;
line 50 }
So if I am reading correctly, it is saying the path is empty. But I know that path works in other apps and it is not empty.
Click to expand...
Click to collapse
I don't think you can call an Environment method when static class variables are Initialised make sure that your String is the correct path with Logs, I would probably make that an instance variable instead...
SimplicityApks said:
I don't think you can call an Environment method when static class variables are Initialised make sure that your String is the correct path with Logs, I would probably make that an instance variable instead...
Click to expand...
Click to collapse
It may kinda look like I know what I'm doing, but looks are deceiving.
I really have no clue what I am doing. I consider myself a hack. I can some what look at code and then make it do what I want, but to actually program something new... I will see if I can't figure that out. But I really do appreciate your help.
StEVO_M said:
It may kinda look like I know what I'm doing, but looks are deceiving.
I really have no clue what I am doing. I consider myself a hack. I can some what look at code and then make it do what I want, but to actually program something new... I will see if I can't figure that out. But I really do appreciate your help.
Click to expand...
Click to collapse
Well then you should probably get started on a simpler app you've built yourself rather than trying to understand this very complex Gallery app (which in my view is poorly commented and documented)...
I had a closer look at the source and it seems that we are on the right track because the _PATH s are used in the getTopSetPath method of the DataManager, and a search reveals that it is called by various activities and pickers. If you're using one of those in your app we should be right.
Now let's get back to the basics, when the app is launched, the default launcher activity is Gallery.java. During it's creation, either startDefaultPage, startGetContent or startViewAction is called, but all of them have the following call:
Code:
data.putString(AlbumSetPage.KEY_MEDIA_PATH, getDataManager().getTopSetPath(DataManager.INCLUDE_ALL)); // or some other variable
So this is the path where the images are loaded. Honestly, I have no idea what the
Code:
"/combo/{/mtp,/local/all,/picasa/all}"
is doing in the path variable, it has to do something with the Combo classes in the data folder, since the app is loading images from different dirs. You can now call your Environment call there and somehow pass back Strings instead of Paths, but it would be nicer if we could somehow figure out the these Paths are used here. An important class is the LocalPhotoSource.java. That is also where getImage from the DataManager is called. You could have a look at that class as well. Which path do you want the gallery to scan actually? The best solution would be to further experiment with the _PATH String, without calling Environment as well as debugging the whole app from the start, so you can get an idea of how everything is working.
SimplicityApks said:
Well then you should probably get started on a simpler app you've built yourself rather than trying to understand this very complex Gallery app (which in my view is poorly commented and documented)...
I had a closer look at the source and it seems that we are on the right track because the _PATH s are used in the getTopSetPath method of the DataManager, and a search reveals that it is called by various activities and pickers. If you're using one of those in your app we should be right.
Now let's get back to the basics, when the app is launched, the default launcher activity is Gallery.java. During it's creation, either startDefaultPage, startGetContent or startViewAction is called, but all of them have the following call:
Code:
data.putString(AlbumSetPage.KEY_MEDIA_PATH, getDataManager().getTopSetPath(DataManager.INCLUDE_ALL)); // or some other variable
So this is the path where the images are loaded. Honestly, I have no idea what the
Code:
"/combo/{/mtp,/local/all,/picasa/all}"
is doing in the path variable, it has to do something with the Combo classes in the data folder, since the app is loading images from different dirs. You can now call your Environment call there and somehow pass back Strings instead of Paths, but it would be nicer if we could somehow figure out the these Paths are used here. An important class is the LocalPhotoSource.java. That is also where getImage from the DataManager is called. You could have a look at that class as well. Which path do you want the gallery to scan actually? The best solution would be to further experiment with the _PATH String, without calling Environment as well as debugging the whole app from the start, so you can get an idea of how everything is working.
Click to expand...
Click to collapse
I tried Changing the following in LocalAlbumSet.java
public class LocalAlbumSet extends MediaSet {
public static final Path PATH_ALL = Path.fromString("/DCIM/_private/.nomedia/all");
public static final Path PATH_IMAGE = Path.fromString("/DCIM/_private/.nomedia/image");
public static final Path PATH_VIDEO = Path.fromString("/DCIM/_private/.nomedia/video");
and Changing all of the TOP_..._Path s to
// This is the path for the media set seen by the user at top level.
private static final String TOP_SET_PATH = "/local/all";
private static final String TOP_IMAGE_SET_PATH = "/local/image";
private static final String TOP_VIDEO_SET_PATH = "/local/video";
private static final String TOP_LOCAL_SET_PATH = "/local/all";
private static final String TOP_LOCAL_IMAGE_SET_PATH = "/local/image";
private static final String TOP_LOCAL_VIDEO_SET_PATH = "/local/video";
I now see Random Images from /DCIM/_private/.nomedia but not all of them, which is really confusing. But at least it's a start.
StEVO_M said:
I have found a Gallery App on GitHub (https://github.com/sevenler/Android_Gallery2D_Custom) that I have integrated into my own app.
Currently the gallery displays all images from my device. What I would like to have is that it ONLY display the images starting at the folder on my sdcard that I specify such as..
private static String targetPath = Environment.getExternalStorageDirectory().toString() + "/DCIM/_private/.nomedia";
I tried several different modifications but I am really struggling.
I was hoping someone could take a look at the source code for the Gallery App on GitHub and tell me how to change it so it does not scan my entire device.
Thanks in advance!!
-Steve
Click to expand...
Click to collapse
Android gallery will not scan any folder having a .nomedia file in it.
EatHeat said:
Android gallery will not scan any folder having a .nomedia file in it.
Click to expand...
Click to collapse
So I am guessing there is no way to Force your own instance to scan it????
StEVO_M said:
So I am guessing there is no way to Force your own instance to scan it????
Click to expand...
Click to collapse
Delete the .nomedia file.
Lol. Not an option if I want to hide my pic.
Sent from my HTCONE using Tapatalk
Not sure what you are trying to achieve, if you want to scan it then why would you want to hide it?
If you want to add an option to allow it to scan or not, you could backup the .nomedia to another directory and delete it for the time being.
Just an idea, can't say for sure. Didn't try it ever.
I have created an app to hide pictures. Currently I have a very basic gallery. I was trying integrate this gallery because it has a lot more option such as editing and adding filters and such.
Sent from my HTCONE using Tapatalk
StEVO_M said:
I have created an app to hide pictures. Currently I have a very basic gallery. I was trying integrate this gallery because it has a lot more option such as editing and adding filters and such.
Click to expand...
Click to collapse
Well why do you need to? Make your app fulfill only one purpose, so let it hide the pictures (I guess by moving a .nomedia file into the folder right?) and then just create a shortcut in your app to the gallery app so the user can still use their preferred one... Makes more sense to me and is way less work.
StEVO_M said:
I have created an app to hide pictures. Currently I have a very basic gallery. I was trying integrate this gallery because it has a lot more option such as editing and adding filters and such.
Sent from my HTCONE using Tapatalk
Click to expand...
Click to collapse
A far more simple and logical way would be to create a hidden folder on the SD card with a .nomedia file in it. Images/videos that are to be hidden can be moved to that location. This would keep it hidden from the gallery and can only be accessed through your private gallery.
For unhiding media, just move them back to their original folders.
Let me try to explain further... As I said, I have created an app already that does the Basic things.
My Application looks like a standard App, a "To Do List", but if you press and hold an Icon on the main screen it prompts you for a Password (These passwords are setup on first use).
Now... Depending on which password you enter, it will either take you to the hidden Gallery OR if you enter a different password it will take you to a Hidden To Do List. This is so anyone that may stumble upon your app, you can show them that it's has a hidden area of the app. This way they have no clue you really have a Hidden Gallery.
If you enter the Hidden Gallery password then it would of course, take you to the hidden gallery.
The Current Features are...
Import from Main Gallery
Pinch to Zoom
Swipe
Share
Restore back to Main Gallery
Delete
Quick Escape ------ "Quick Escape" can be activate 2 ways. If you shake the phone while in the Hidden Gallery, the image will change to an image of your choosing or the default one that is set during install. OR..... A less obvious "Quick Escape" ... While in the Hidden Gallery, press the volume up or down and the image will switch. Either way, once it is in that mode, you can not press back. the only way out it to press the home button. This is designed so if someone grabs the phone out of your hand they will only see they Quick Escape" image and pressing back will not take them back to the gallery.
My app also appears in the standard Share menu, so if you are in your Main Gallery and want to hide a picture, you can share it to my app and it will then hide the picture.
I want to add More features to my Gallery, such as Filters, Editing (crop, rotate...), Frames... All the same things that you can do in the Main Gallery. The only thing I really don't want or need is a Camera function. I can't see someone taking the time to open my app and then get to the Hidden Gallery and then taking a picture, just so they can hide an image. Most would just take the picture as they always would and then "Share" it to my app.
I hope this explains Why I want to use the other Gallery rather than reinventing the wheel that already has all of these features built in. If I can not get that to work, maybe I can just pull the Features out and use those.
Anyone who wants to actually See the app in action, PM me and I will send you a DropBox link to install. FYI, It requires 4.0 or higher.
When getting a value from any preferences, whether private Activity or default shared preferences, you would normally have to get a reference to a SharedPreferences instance, for example using
Code:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(someContext);
Only after that we can start getting/saving the values, such as
Code:
String username = prefs.getString("username", "");
prefs.edit().putString("username", "androiduser").apply();
This can get tedious if the values need to be saved and retrieved from multiple places as the caller is always required to supply the key of the preference, know under what type it is saved, and know what default should be used. This can also become error prone as more keys get used. Putting commonly accessed preferences behind a wrapper is a reasonable solution, but still requires some boilerplate code.
What if however we could define an interface like
Code:
public interface MyPreferences {
@KeyByString("username")
String getUsername();
@KeyByString("username")
void setUsername(String value);
}
for everyone to use in order to save and get values? The caller doesn't need to worry about the key, neither needs to think about what type the key should use, and the process of retrieving/saving is hidden behind a method name with improved semantics.
With StoreBox that becomes reality. Given the above interface definition you can easily create an instance of the interface using
Code:
MyPreferences prefs = StoreBox.create(context, MyPreferences.class);
and you will be able to retrieve/save the value just by calling the defined methods
Code:
String username = prefs.getUsername();
prefs.setUsername("androiduser");
You can read more about the project here, including details on how it can be used and added to a project.
Let me know what you think and whether you find it useful. Thanks!
great! ty
Great work!