I'm working on a small learning-tool project that has several different views displayed in various fragments. What I'd like to do is when the user selects a layout or view (e.g. TextView), a dialog pops up that shows all its available attributes (e.g. android:layout_width, android:layout_height, android:focusable, etc). Rather than going through each layout/view and manually typing the attributes in a file or class, I was hoping there was a way to programmatically get the attributes. Currently, I just have a JSON file I'm reading from, but it's becoming extremely tedious. An issue also arises with different API versions.
Just to get an idea of what I'm currently dealing with, here's my JSON file:
{
"LayoutParams": [
"android:layout_height",
"android:layout_width"
],
"MarginLayoutParams": [
"android:layout_margin",
"android:layout_marginBottom",
"android:layout_marginEnd",
"android:layout_marginHorizontal",
"android:layout_marginLeft",
"android:layout_marginRight",
"android:layout_marginStart",
"android:layout_marginTop",
"android:layout_marginVertical"
],
"RelativeLayout": {
"inherited_properties": [
"MarginLayoutParams",
"LayoutParams"
],
"primary_properties": [{
"android:gravity": ["bottom", "center", "center_horizontal", "center_vertical", "clip_horizontal", "clip_vertical", "end", "fill", "fill_horizontal", "fill_vertical", "left", "right", "start", "top"],
"android:ignoreGravity": [""],
"android:layout_above": [],
"android:layout_alignBaseline": [],
"android:layout_alignBottom ": [],
"android:layout_alignEnd": [],
"android:layout_alignLeft": [],
"android:layout_alignParentBottom": [],
"android:layout_alignParentEnd": [],
"android:layout_alignParentLeft": [],
"android:layout_alignParentRight": [],
"android:layout_alignParentStart": [],
"android:layout_alignParentTop": [],
"android:layout_alignRight": [],
"android:layout_alignStart": [],
"android:layout_alignTop": [],
"android:layout_alignWithParentIfMissing": [],
"android:layout_below": [],
"android:layout_centerHorizontal": [],
"android:layout_centerInParent": [],
"android:layout_centerVertical": [],
"android:layout_toEndOf": [],
"android:layout_toLeftOf": [],
"android:layout_toRightOf": [],
"android:layout_toStartOf": []
}]
}
}
You can extract them from R.stylable.
AFAIK, there's no XML schema or DTD defined, so R.stylable might be your only choice.
Related
I want to receive emoticon from emoji-datasource site as json file and show it in android. How do you do it? The file in json format is:
[
{
"name": "HASH KEY",
"unified": "0023-FE0F-20E3",
"non_qualified": "0023-20E3",
"docomo": "E6E0",
"au": "EB84",
"softbank": "E210",
"google": "FE82C",
"image": "0023-fe0f-20e3.png",
"sheet_x": 0,
"sheet_y": 0,
"short_name": "hash",
"short_names": [
"hash"
],
"text": null,
"texts": null,
"category": "Symbols",
"sort_order": 132,
"added_in": "0.0",
"has_img_apple": true,
"has_img_google": true,
"has_img_twitter": true,
"has_img_facebook": false
},
{
"name": null,
"unified": "002A-FE0F-20E3",
"non_qualified": "002A-20E3",
"docomo": null,
"au": null,
"softbank": null,
"google": null,
"image": "002a-fe0f-20e3.png",
"sheet_x": 0,
"sheet_y": 1,
"short_name": "keycap_star",
"short_names": [
"keycap_star"
],
"text": null,
"texts": null,
"category": "Symbols",
"sort_order": 133,
"added_in": "0.0",
"has_img_apple": true,
"has_img_google": true,
"has_img_twitter": true,
"has_img_facebook": false
},
...
]
Link is here : https://www.npmjs.com/package/emoji-datasource.
I tried the following but it didn't work.
textView.text = String(Character.toChars(0x002AFE0F20E3))
I want to show the user all the emoticons available on the Android device.
Oh, I solved it. Just use in json file google name code.
I dont know that this would serve as a solution but I did something different and wanna share it here so everyone knows.
Content that I create from Android app gets encoded using this. When fetching from server, I decode this using the same method. Content includes emojis as well and they appear perfectly in all devices without knowing the names of the emojis.
I am trying to parse JSON data which looks like this in android;
{
"data": [{
"http_code": 200,
"message": "success",
"created_at": "2016/10/12",
"categories": [{
"cat_id": 1,
"cat_name": "Business and Commerce",
"subcategories":[{
"subcat_id": 1,
"subcat_name": "Intellectual Property",
"articles":[{
"article_id": 1,
"article_heading": "What is intellectual?",
"article_url": "http://example.com/1"
},{
"article_id": 2,
"article_heading": "Types of intellectual Properties",
"article_url": "http://example.com/2"
}]
}, {
"subcat_id": 2,
"subcat_name": "Business Licensing",
"articles":[{
"article_id": 1,
"article_heading": "What is a license?",
"article_url": "http://example.com/1"
},{
"article_id": 2,
"article_heading": "Types of Business Licenses",
"article_url": "http://example.com/2"
}]
}]
}, {
"cat_id": 2,
"cat_name": "Family Law",
"subcategories":[{
"subcat_id": 3,
"subcat_name": "Domestic Violence",
"articles":[{
"article_id": 1,
"article_heading": "What is domestic violene?",
"article_url": "http://example.com/1"
},{
"article_id": 2,
"article_heading": "Types of domestic violence",
"article_url": "http://example.com/2"
}]
}, {
"subcat_id": 4,
"subcat_name": "Marriage",
"articles":[{
"article_id": 1,
"article_heading": "What is a marriage?",
"article_url": "http://example.com/1"
},{
"article_id": 2,
"article_heading": "Types of marriages",
"article_url": "http://example.com/2"
}]
}]
}]
}]
}
I am supposed to see data for a specific node when I select it via a listview list item click and so on....
So far I have managed to parse all the categories and display them in a listview, but I want to display subcategories for a category I select on the listview.
Set an onItemClickListener on your listview and use the position of the selected item to return the relevant subcategories?
For example, perhaps something along the lines of:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Switch(position) {
case 0:
//get first subcategories array values
break;
case 1:
//get second subcategories array values
break;
....
}
}
Use ExpandableListView, example given on this link.
For json parsing use Google gson, it will make your work easy and efficient.
It seems similar to How to parse this nested JSON array in android
But you can use this lib https://github.com/FasterXML/jackson
to make the work easy and faster using Objects.
It is a small tutorial: JacksonInFiveMinutes
Specially: Full Data Binding (POJO) Example. And JacksonDataBinding
Thanks everyone for your help. I finally managed to solve the issue;
Here is how I did it;
JSONObject jsonObj = new JSONObject(jsonStr);
JSONObject subcategories = jsonObj.getJSONObject("data").getJSONArray("categories").getJSONObject((int)getItemId(position));
Log.e("TAG","Subcategories: " + subcategories);
I don't know if that is the correct way, but it worked in my case.
I am implementing the Bing search for image searching.
I refered this link, and change my response to JSON.
It works and the result is like:
{
"d": {
"results": [{
"__metadata": {
"uri": "https://api.datamarket.azure.com/Data.ashx/Bing/Search/Image?Query=\u0027Pepsi\u0027&$skip=0&$top=1",
"type": "ImageResult"
},
"ID": "64737694-fc53-4d68-933d-10edc214fd3a",
"Title": "Pepsi: Like Madonna, its look has been reinvented time and time again ...",
"MediaUrl": "http://tjthesportsgeek.files.wordpress.com/2012/02/pepsi.png",
"SourceUrl": "http://tjthesportsgeek.com/2012/02/14/tale-of-the-tape-coke-vs-pepsi/",
"DisplayUrl": "tjthesportsgeek.com/2012/02/14/tale-of-the-tape-coke-vs-pepsi",
"Width": "1588",
"Height": "2064",
"FileSize": "569827",
"ContentType": "image/png",
"Thumbnail": {
"__metadata": {
"type": "Bing.Thumbnail"
},
"MediaUrl": "http://ts2.mm.bing.net/th?id=OIP.M7f9b9a39639b9ca8bb6f1cba6e35d041H0&pid=15.1",
"ContentType": "image/jpg",
"Width": "369",
"Height": "480",
"FileSize": "19879"
}
},
// Next array element
]
}
}
but what i need is:
The json result with only MediaUrl and MediaUrl of Thumbnail. (As it is possible in Google Custom Search with the help of tag "field" like fields=items(link,image/thumbnailLink))
The image only with medium size. (I searched for this and applied the filter but of no use.)
Please reply with your valuable suggestions.
You can't filter output fields.
Use the parameter: ImageFilters = Size.Medium
My ref: https://onedrive.live.com/view.aspx?resid=9C9479871FBFA822!109&app=Word&authkey=!ACvyZ_MNtngQyCU
In my android app, I want users to be able to enter a twitter username and from there the twitter app launches on the entered username's page. I did some research and found out the link needed to open the twitter app from another app is twitter://user?user_id=id_num I was wondering if there is a way to get the user's twitter id from a twitter username in Android so I can make this happen. Any help would be greatly appreciated, thank you.
You should read through the Twitter API, in particular the section about user lookups
Edit: Links updated to current Twitter API docs though answer remains targeted at API v1.1 as when asked.
That particular request has optional fields to search by id or screen_name and will return a list of matches which you can parse for user ids. So you can search by screen_name and read the response to get an id.
The request you are (were) looking for is:
GET https://api.twitter.com/1/users/lookup.json?screen_name=somename
The provided response in the API examples is (was):
[
{
"name": "Twitter API",
"profile_sidebar_border_color": "87bc44",
"profile_background_tile": false,
"profile_sidebar_fill_color": "e0ff92",
"location": "San Francisco, CA",
"profile_image_url": "http://a3.twimg.com/profile_images/689684365/api_normal.png",
"created_at": "Wed May 23 06:01:13 +0000 2007",
"profile_link_color": "0000ff",
"favourites_count": 2,
"url": "http://apiwiki.twitter.com",
"contributors_enabled": true,
"utc_offset": -28800,
"id": 6253282,
"profile_use_background_image": true,
"profile_text_color": "000000",
"protected": false,
"followers_count": 160752,
"lang": "en",
"verified": true,
"profile_background_color": "c1dfee",
"geo_enabled": true,
"notifications": false,
"description": "The Real Twitter API. I tweet about API changes, service issues and appily answer questions about Twitter and our API. Don't get an answer? It's on my website.",
"time_zone": "Pacific Time (US & Canada)",
"friends_count": 19,
"statuses_count": 1858,
"profile_background_image_url": "http://a3.twimg.com/profile_background_images/59931895/twitterapi-background-new.png",
"status": {
"coordinates": null,
"favorited": false,
"created_at": "Tue Jun 22 16:53:28 +0000 2010",
"truncated": false,
"text": "#Demonicpagan possible some part of your signature generation is incorrect & fails for real reasons.. follow up on the list if you suspect",
"contributors": null,
"id": 16783999399,
"geo": null,
"in_reply_to_user_id": 6339722,
"place": null,
"source": "TweetDeck",
"in_reply_to_screen_name": "Demonicpagan",
"in_reply_to_status_id": 16781827477
},
"screen_name": "twitterapi",
"following": false
},
{
"name": "Twitter",
"profile_sidebar_border_color": "EEEEEE",
"profile_background_tile": false,
"profile_sidebar_fill_color": "F6F6F6",
"location": "San Francisco, CA",
"profile_image_url": "http://a1.twimg.com/profile_images/878669694/twitter_bird_normal.jpg",
"created_at": "Tue Feb 20 14:35:54 +0000 2007",
"profile_link_color": "038543",
"favourites_count": 2,
"url": "http://twitter.com",
"contributors_enabled": true,
"utc_offset": -28800,
"id": 783214,
"profile_use_background_image": true,
"profile_text_color": "333333",
"protected": false,
"followers_count": 3305606,
"lang": "en",
"verified": true,
"profile_background_color": "ACDED6",
"geo_enabled": true,
"notifications": false,
"description": "Always wondering what's happening. ",
"time_zone": "Pacific Time (US & Canada)",
"friends_count": 257,
"statuses_count": 774,
"profile_background_image_url": "http://s.twimg.com/a/1276896641/images/themes/theme18/bg.gif",
"status": {
"coordinates": null,
"favorited": false,
"created_at": "Tue Jun 22 16:40:19 +0000 2010",
"truncated": false,
"text": "9 cool things to do with your Twitter account (via #pastemagazine) http://example.com",
"contributors": [
16739704
],
"id": 16783169544,
"geo": null,
"in_reply_to_user_id": null,
"place": null,
"source": "web",
"in_reply_to_screen_name": null,
"in_reply_to_status_id": null
},
"screen_name": "twitter",
"following": false
}
]
So you can access the id from the results by parsing that JSON response for the "id" field.
Note however that the returned is a JSON array of results and not just a single definitive answer. You will need to work out yourself which is the correct one (order is not guaranteed either so do not assume the first entry is the most likely).
Also worth noting is that even though this is documented as returning 'id' and an integer value, the current preferred usage of ids is to supply 'id_str' and a string representation of the integer. This is due to inconsistencies in how various platforms handle and limit integers. So even if you receive 'id' you should use 'id_str' for future interactions.
Assuming you have a bearer token from the Twitter Developer Platform, you can get the id for a given username with the Twitter API v2 users lookup endpoint.
So for example, if I send an authorized GET request to
https://api.twitter.com/2/users/by?usernames=TwitterDev,TwitterAPI
Response:
{
"data": [
{
"id": "2244994945",
"name": "Twitter Dev",
"username": "TwitterDev"
},
{
"id": "6253282",
"name": "Twitter API",
"username": "TwitterAPI"
}
]
}
Python Code Example:
import requests
bearer_token = '<YOUR_TWITTER_BEARER_TOKEN_HERE>'
headers = {"Authorization": f"Bearer {bearer_token}"}
params = {"usernames": "TwitterDev,TwitterAPI"}
url = "https://api.twitter.com/2/users/by"
# Get list of twitter follows
r = requests.get(url, params=params, headers=headers, timeout=20)
if r.status_code != 200:
raise Exception(
"Request returned an error: {} {}".format(
r.status_code, r.text
)
)
json_response = r.json()
for u in json_response['data']:
username = u['username']
id = u['id']
print(f"The user id for {username} is {id}")
Output:
The user id for TwitterDev is 2244994945
The user id for TwitterAPI is 6253282
See also:
Twitter Developer Platform - Users lookup
Twitter APIv2 sample code - get_users_with_bearer_token.py
TweeterID - Twitter ID and username converter
I need to create dynamic layout (i.e. without using xml at all ). On the mobile device an service api will provide jsons. These jsons will hold the layout pattern or design to draw dynamically.
These layout jsons will coresspond to different templates that we need to show. It can be more than 150 templates.
Please find below a sample template :-
Template.json
{
"data": {
"layouts": [
{
"layoutId": 0,
"width": "34%",
"selectedbackgroundcolor": "#96F2CD",
"gradient": true,
"backgroundcolor": "#afeeb9",
"gradientcolors": [
"#afeeb9",
"#f3f6f7"
],
"strokewidth": 1,
"strokecolor": "#7bad51",
"children": [
{
"children": [
{
"backgroundcolor": "#3074c6",
"type": "label",
"field": "textfield1",
"fontsize": 14,
"textcolor": "#FFFFFF",
"alignment": "right",
"width": 242,
"singleline": true,
"topmargin": 10,
"rightmargin": 10,
"rightpadding": 10,
"bottompadding": 5,
"toppadding": 5
},
{
"backgroundcolor": "#3074c6",
"type": "label",
"text": "textfield: #",
"dependonfield": "textfield1",
"fontsize": 14,
"topmargin": 10,
"textcolor": "#FFFFFF",
"alignment": "right",
"width": 95,
"singleline": true,
"leftpadding": 10,
"bottompadding": 5,
"toppadding": 5,
"leftmargin": 10
}
]
},
{
"children": [
{
"type": "label",
"field": "FormattedClosedDate",
"fontsize": 14,
"textcolor": "#000000",
"alignment": "right",
"width": 90,
"topmargin": 5,
"singleline": true,
"rightmargin": 10
},
{
"type": "label",
"text": "Closed On: ",
"dependonfield": "FormattedClosedDate",
"fontsize": 14,
"topmargin": 5,
"textcolor": "#000000",
"alignment": "right",
"width": 100,
"singleline": true,
"leftmargin": 5,
"bold": true
}
]
},
{
"children": [
{
"type": "label",
"field": "Title",
"textcolor": "#000000",
"alignment": "left",
"fontsize": 17,
"bold": true,
"singleline": true,
"topmargin": 10,
"leftmargin": 10,
"rightmargin": 10
}
]
},
{
"children": [
{
"type": "label",
"field": "Summary",
"textcolor": "#7E957B",
"alignment": "left",
"fontsize": 14,
"leftmargin": 10,
"bottompadding": 20,
"maxline": 2,
"rightmargin": 10
}
]
}
]
}
]
},
"rcode": 100,
"msg": "Success"
}
I wrote the layout parser for these templates. I choose Listview to dynamically inflate the view that was returned from layout parse. Each listview's row is now holding different layout view or template.
So I cannot use the view holder pattern to reuse the view's elements. As views are created dynamically so the view id's are created dynamically.
I am showing 15 items in a list at single point of time. I am using this library to load n items form total x items at aingle point in time---https://github.com/chrisbanes/Android-PullToRefresh.
Now the problems are :-
Memory leak because we are not using the view holder pattern.
Context is used to create new views they are coupled from activities
life cycle.
Views are not destroyed until activity is not destroyed.
Please provide me with an alternate solution of using other than Listview or modify the current approach.
The most important thing for you is be sure to implement Adapter.getItemViewType. Each layout should have its own type identifier. Your convertView parameter, if set, will then always have the correct layout already inflated.
Now you can use the holder pattern again, by using a different holder for each layout.
Edit: I don't think your situation is well suited to ListView. ListView is meant for generally large lists of similar content. Have you considered a vertically oriented LinearLayout within a ScrollView instead?
If your layouts are all different, you have to decide between dynamically generating them in an Adapter (the ListView approach you're already using) which will be slow, or generating them all at once, which might take more memory.
As for your specific concerns:
* Not using Holder pattern does not introduce a memory leak. You might be misunderstanding the purpose of Holder pattern. It's only intended to reduce re-inflation of similar layouts.
* Even with views created from within an Adapter, they're still created with your activity's context. They are UI elements, so will always be bound to the Activity lifecycle.