ListView item background changes depending on scroll position - android
I'm running into a very strange ListView behaviour. I have a simple chat application which uses a ListView and a custom implementation of BaseAdapter to show messages.
The idea I had was to shade messages from the "local" user grey and have messages from the "remote" user white, to help the user distinguish between the two.
The two screenshots below show what's happening. The second is the exact same activity, xml etc etc, simply scrolled down a bit.
Scrolled up:
Scrolled down:
Look at the message sent by "Me" # 23:05. When at the top it has no contrast to its neighbours, but when it is scrolled to the bottom, the difference is clear to see.
This occurs on a nexus 4 and 7 on 4.2.2, and a GS3 running 4.1.2.
Here is the XML for one of the ListView items:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/activity_view_conversation_message_list_item_wrapper"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="2dp"
android:paddingLeft="5dp"
android:paddingRight="10dp" >
<ImageView
android:id="#+id/activity_view_conversation_message_list_item_user_image"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_marginTop="5dp"
android:src="#drawable/default_user_image" />
<TextView
android:id="#+id/activity_view_conversation_message_list_item_heading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="1dp"
android:layout_toRightOf="#+id/activity_view_conversation_message_list_item_user_image"
android:text="Martyn"
android:textColor="#000000"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="#+id/activity_view_conversation_message_list_item_contents"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/activity_view_conversation_message_list_item_heading"
android:layout_marginLeft="10dp"
android:layout_marginRight="5dp"
android:layout_marginTop="2dp"
android:layout_toLeftOf="#+id/activity_view_conversation_message_list_item_ack"
android:layout_toRightOf="#+id/activity_view_conversation_message_list_item_user_image"
android:text="Hello this is some text"
android:textColor="#333333"
android:textIsSelectable="true"
android:textSize="18sp" />
<TextView
android:id="#+id/activity_view_conversation_message_list_item_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginTop="2dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="2dp"
android:text="12:08"
android:textSize="14sp" />
<ImageView
android:id="#+id/activity_view_conversation_message_list_item_ack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/activity_view_conversation_message_list_item_time"
android:layout_marginRight="2dp"
android:layout_marginTop="8dp"
android:layout_toLeftOf="#+id/activity_view_conversation_message_list_item_time"
android:src="#drawable/red_dot_8dp" />
</RelativeLayout>
And here is where I set the colour of the RelativeLayout:
if(localUserId.equals(remoteUserId)){
itemLayout.setBackgroundColor(Color.parseColor("#F9F9F9"));
}
That code runs inside the getView() method of my Adapter.
I've Googled this a fair bit and turned up nothing, there are a lot of SO questions regarding the android:cacheColorHint issue but I don't think that is what is going on here.
Has anyone run into this before? I'm stumped!
EDIT: Here's the baseadapter code:
public class MessageListAdapter extends BaseAdapter {
private ArrayList<Message> messageList;
Context context;
/**
* Constructor
* #param newConversationsList An ArrayList of Conversation objects that this adapter will use
* #param newContext The context of the activity that instantiated this adapter
*/
MessageListAdapter(ArrayList<Message> newMessageList, Context newContext){
messageList = newMessageList;
//reload();
context = newContext;
}
public int getCount() {
return messageList.size();
}
public Object getItem(int position) {
return messageList.get(position);
}
public long getItemId(int position) {
return position;
}
/**
* Adds a message to the chat list
* #param message A Message object containing all the message's information
*/
public void add(Message message){
//nMessagesToShow++; //A new message has been added, so increase the number to show by one
Log.d(TAG, "COUNT: "+getCount());
//refresh();
}
public void refresh(){
this.notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if(view!=null){
//return view;
}
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//Get the Message object from the list
Message message = messageList.get(position);
//Get the data from the message
String senderId = message.getFromUser();
int messageType = message.getType();
String senderFirstName;
ImageView userImage, messageImage;
TextView messageHeading, messageBody;
switch(messageType){
case Message.MESSAGE_TYPE_TEXT: //Standard text message
//The layout we inflate for this list item will vary depending on whether this message has the same sender as the previous
if(position>0 && senderId.equals(messageList.get(position-1).getFromUser())){ //True if this is not the first message AND the sender id matches that of the previous message
view = vi.inflate(R.layout.activity_view_conversation_message_list_item_alternate, null); //Inflate an alternate version of the list item which has no heading or user image
}
else{ //This is the first message OR the sender id is different to the previous
view = vi.inflate(R.layout.activity_view_conversation_message_list_item, null); //Inflate the standard version of the layout
userImage = (ImageView) view.findViewById(R.id.activity_view_conversation_message_list_item_user_image);
messageHeading = (TextView) view.findViewById(R.id.activity_view_conversation_message_list_item_heading);
//Use the sender's ID to get the sender's image and first name
Contact contact = database.getContact(senderId);
if(senderId.equals(localUserId)){ //True if the local user sent this message
senderFirstName = "Me";
}
else{
senderFirstName = contact.getFirstName();
}
userImage.setImageBitmap(contact.getImageBitmap(100, 100, 6));
messageHeading.setText(senderFirstName);
}
messageBody = (TextView) view.findViewById(R.id.activity_view_conversation_message_list_item_contents);
messageBody.setText(message.getContents(null));
break;
case Message.MESSAGE_TYPE_IMAGE: //Image message
view = vi.inflate(R.layout.activity_view_conversation_message_list_item_image, null); //Inflate a list item template for displaying an image
userImage = (ImageView) view.findViewById(R.id.activity_view_conversation_message_list_item_user_image);
//Sender's first name
messageHeading = (TextView) view.findViewById(R.id.activity_view_conversation_message_list_item_heading);
Contact contact = database.getContact(senderId);
if(senderId.equals(localUserId)){ //True if the local user sent this message
senderFirstName = "Me";
}
else{
senderFirstName = contact.getFirstName();
}
messageHeading.setText(senderFirstName);
messageImage = (ImageView) view.findViewById(R.id.activity_view_conversation_message_list_item_image);
String imageResourceId = null;
//The message is a JSON object containing several fields, one of which is the file name which we will use to get the image
try {
JSONObject messageJSON = new JSONObject(message.getContents(null));
String imagePath = Environment.getExternalStorageDirectory()+"/epicChat/resources/"+messageJSON.getString("fileName");
int imageWidth = messageJSON.getInt("width"); //We want the dimensions in order to calculate the aspect ratio of the image
int imageHeight = messageJSON.getInt("height");
if(messageJSON.has("resourceId")){
imageResourceId = messageJSON.getString("resourceId"); //This is used when opening the image gallery
}
int displayWidth = 300;
int displayHeight = (int) ((float) imageHeight / (float) imageWidth * (float) displayWidth);
String imagePathFull = imagePath+displayWidth+displayHeight; //For the caching
Bitmap originalImage = null;
//Check the bitmap cache exists. If not, reinstantiate it
if(MainActivity.bitmapCache==null){ //Cache is null
MainActivity.loadBitmapCache();
}
else{ //Cache is not null, so check it to see if this image is in it
originalImage = MainActivity.bitmapCache.get(imagePathFull);
}
if(originalImage==null){ //True if the bitmap was not in the cache. So we must load from disk instead
new Utils.LoadBitmapAsync(imagePath, messageImage, displayWidth, displayHeight, MainActivity.bitmapCache).execute();
messageImage.getLayoutParams().height = displayHeight;
}
else{
messageImage.setImageBitmap(originalImage);
}
}
catch (JSONException e) {
Log.e(TAG, "Error reading image JSON: "+e.toString());
}
if(imageResourceId!=null){ //Only attach the listener if we got a valid resource ID
final String recourceIdFinal = imageResourceId;
final String conversationIdFinal = message.getUserList();
messageImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent showConversationImageGalleryIntent = new Intent(context, ViewConversationImageGalleryActivity.class);
showConversationImageGalleryIntent.putExtra("conversationId", conversationIdFinal);
showConversationImageGalleryIntent.putExtra("resourceId", recourceIdFinal);
startActivityForResult(showConversationImageGalleryIntent, ACTION_SHOW_CONVERSATION_IMAGE_GALLERY);
}
});
}
userImage.setImageBitmap(contact.getImageBitmap(100, 100, 6));
break;
case Message.MESSAGE_TYPE_INVALID:
default:
break;
}
//Some layout items are present in all layouts. Typically these are the status indicator and the message time
RelativeLayout itemLayout = (RelativeLayout) view.findViewById(R.id.activity_view_conversation_message_list_item_wrapper);
//If the message is from the local user, give it a subtle grey background
if(localUserId.equals(message.getFromUser())){
itemLayout.setBackgroundColor(Color.parseColor("#E9E9E9"));
}
else{
itemLayout.setBackgroundColor(Color.parseColor("#FFFFFF"));
}
TextView messageTimeText = (TextView) view.findViewById(R.id.activity_view_conversation_message_list_item_time);
messageTimeText.setText(message.getFormattedTime());
ImageView messageStatusImage = (ImageView) view.findViewById(R.id.activity_view_conversation_message_list_item_ack);
//Set the status image according to the status of the message
switch(message.getStatus()){
case Message.MESSAGE_STATUS_PENDING: //Pending messages should have a red dot
messageStatusImage.setImageResource(R.drawable.red_dot_8dp);
messageStatusImage.setVisibility(View.VISIBLE);
break;
case Message.MESSAGE_STATUS_ACK_SERVER: //Messages that reached the server should have an orange dot
messageStatusImage.setImageResource(R.drawable.orange_dot_8dp);
messageStatusImage.setVisibility(View.VISIBLE);
break;
case Message.MESSAGE_STATUS_ACK_RECIPIENT: //Messages that reached the recipient should have an green dot
messageStatusImage.setImageResource(R.drawable.green_dot_8dp);
messageStatusImage.setVisibility(View.VISIBLE);
break;
case Message.MESSAGE_STATUS_NOT_SET: //Not set typically means the message came from another user, in which case the status image should be hidden
default: //Also default here
messageStatusImage.setVisibility(View.INVISIBLE);
break;
}
return view;
}
}
Since there's no else statement matching your if, this is probably due to view recycling. When an item from a ListView scrolls off the screen, the operating system removes it and hands it back to the adapter in the same state it was removed. This means you need to set the background color when it's not the local user's message as well.
Related
TextView not updated
I have a text view that is supposed to change as some checkboxes are clicked. A user has a certain amount of free points with which to purchase attributes. When a checkbox is clicked the points are decreased. When a checkbox is unchecked, the points it cost to check it are supposed to be refunded to the total free points, but that's not the case in the current code that I have. The code for the checkboxes is straightforward: <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="#+id/class_container" android:layout_below="#id/stats_container" android:layout_alignParentLeft="true" android:layout_alignParentStart="true"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="#string/class_select" android:textSize="24sp" android:id="#+id/class_description" android:layout_alignParentTop="true" android:layout_centerHorizontal="true"/> <CheckBox android:layout_below="#id/class_description" android:id="#+id/checkbox_noble" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="#string/class_noble" android:onClick="creationClassClick"/> <CheckBox android:layout_below="#id/class_description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="#+id/checkbox_warrior" android:text="#string/class_warrior" android:layout_toEndOf="#+id/checkbox_noble" android:layout_toRightOf="#+id/checkbox_noble" android:onClick="creationClassClick"/> <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="#+id/checkbox_wizard" android:text="#string/class_wizard" android:layout_below="#+id/checkbox_noble" android:onClick="creationClassClick"/> <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="#+id/checkbox_trader" android:text="#string/class_trader" android:layout_below="#id/checkbox_warrior" android:layout_toEndOf="#+id/checkbox_wizard" android:layout_toRightOf="#+id/checkbox_wizard" android:onClick="creationClassClick"/> </RelativeLayout> The relevant methods here are as follows: public void pointChange(final int amt){ Runnable updateTextView = new Runnable() { #Override public void run() { TextView tv = findViewById(R.id.free_points); tv.setText(String.valueOf(amt)); } }; runOnUiThread(updateTextView); } public void creationClassClick(View v){ int freePoints = Integer.parseInt(freePts.getText().toString()); if(lastPointsUsed > 0){ int addedBack = freePoints + lastPointsUsed; pointChange(addedBack); freePoints = Integer.parseInt(freePts.getText().toString()); lastPointsUsed = 0; } String targetFull = A.getResources().getResourceEntryName(v.getId()); String[] target = targetFull.split("_"); boolean query; int cost = 1; int error; int cause; switch(target[1]){ case "noble": warriorCheck.setChecked(false); wizardCheck.setChecked(false); traderCheck.setChecked(false); cost = 12; break; case "warrior": wizardCheck.setChecked(false); nobleCheck.setChecked(false); traderCheck.setChecked(false); cost = 8; break; case "wizard": warriorCheck.setChecked(false); nobleCheck.setChecked(false); traderCheck.setChecked(false); cost = 9; break; case "trader": warriorCheck.setChecked(false); wizardCheck.setChecked(false); nobleCheck.setChecked(false); cost = 10; break; } lastPointsUsed = cost; query = (freePoints - cost < 0); error = R.string.creation_no_points; cause = freePoints - cost; if(query){ new Modal(app, true, R.string.oops, error, 0, 0); }else{ this.classType = target[1]; pointChange(cause); } } When i use the pointChange() method from any other method in this activity, it works fine. Its only when unchecking a checkbox that it fails. I've searched google and SO for the answer, and the best I could come up with is the runnable set to runonuithread, but it doesn't work either. Any help would be greatly appreciated. --EDIT-- The appropriate views are retrieved via Butterknife, but this is literally the only code other than the xml that deals with them: #BindView(R.id.free_points) TextView freePts; #BindView(R.id.checkbox_noble) CheckBox nobleCheck; #BindView(R.id.checkbox_warrior) CheckBox warriorCheck; #BindView(R.id.checkbox_wizard) CheckBox wizardCheck; #BindView(R.id.checkbox_trader) CheckBox traderCheck;
Getting values of EditTexts from multiple Layouts in Android not working?
Not asked a question in a while so it's been long overdue! I am creating an app where job items can be created onClick, with each new row containing a Description(EditText), a Price(EditText) and a button to delete the current row, but I am having trouble when getting the values from the EditText fields when there is more than one row - it just returns the values of the newest row. Aside from the 'Job List Container', the views are created dynamically so pardon the lack of XML, but the structure of what I am trying to achieve is as follows, where clicking the Add button adds a row (this can be multiple rows) and clicking the submit button takes all of the Description and Price values and processes them (adds the prices and adds the job to the DB): ...and this is the code I've written for it called from the addNewJobRow onClick listener (all together for simplicity): private void addJobItem() { //Create a new row container final LinearLayout jobRowContainer = new LinearLayout(this); //Create a new EditText for the Description final EditText description = new EditText(this); description.setHint("Description..."); description.setLayoutParams(new LinearLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f )); //Create an EditText for the Price final EditText price = new EditText(this); price.setHint("00.00"); //Create a new button to delete the row Button delete = new Button(this); delete.setBackgroundColor(Color.RED); delete.setText("X"); //Add Description, Price and Delete to the row container jobRowContainer.addView(description); jobRowContainer.addView(price); jobRowContainer.addView(delete); //Add the Row Container to the Jobs List Container ll_jobListContainer.addView(jobRowContainer); //Get the values of the Description and Price, for each row btn_JobSubmit.setOnClickListener(new View.OnClickListener() { #Override public void onClick(View v) { for (int i = 0; i < ll_jobListContainer.getChildCount(); i++) { for(int j = 0; j < jobRowContainer.getChildCount(); j++) { if (jobRowContainer.getChildAt(i) instanceof EditText){ String descriptionString = description.getText().toString(); String priceString = price.getText().toString(); System.out.println("z! " + descriptionString + " # " + priceString); } } } } }); } I have tried a couple of iterations of this with and without the nested FOR loops and with and without the use of instanceof, but all it does is print out the newest row. So, if I have multiple job rows, how can I get all of the values as required? Thanks for your time and all that nice stuff xxx
The basic problem is that you're using only the last instance of description and price instead of each rows instance. (This may be what Dmitry is saying as well). To fix it, you need to get the input for each row. Here's one way. Set an ID for description & price. (You can't just use '1' or '2', it needs to be a resource type ID so it is guaranteed to be unique). I made a dummy layout file of a row & assigned IDs in that to the 2 EditTexts. There may be a better way to do it. So anyway, add these 2 lines in your declarations descripton.setId(R.id.description); and price.setId(R.id.price); Now this is your onClick() public void onClick(View v) { for (int i = 0; i < ll_jobListContainer.getChildCount(); i++) { LinearLayout currentRow = (LinearLayout)ll_jobListContainer.getChildAt(i); EditText editText = (EditText)currentRow.findViewById(R.id.description); String descriptionString = editText.getText().toString(); editText = (EditText)currentRow.findViewById(R.id.price); String priceString = editText.getText().toString(); Log.d(TAG, "z! " + descriptionString + " # " + priceString); } } EDIT: I didn't want to change this answer since it had already been accepted so I've put a more concise solution in another answer.
Of cause, your last setOnClickListener takes strings String descriptionString = description.getText().toString(); String priceString = price.getText().toString(); Where description and price - is fields in the function (last edittexts). The good way to do that is to use RecyclerView/ListView, in "onTextChangeListner" of ViewHolder save new text to model of this object and print all text from your models, not directly from views.
I normally try to answer only question that was asked rather than change code that's not necessary. However, in this case, since I had created a dummy layout just to get Resource IDs, I wonder if that layout file could be put to use. I had started to change my answer but original one was accepted before I could make the changes. I've put a different version of the solution here. I didn't want to modify an answer that had already been accepted. private void addJobItem() { //Create a new row container LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); LinearLayout jobRowContainer = (LinearLayout)inflater.inflate(R.layout.row_layout, null); //Add the Row Container to the Jobs List Container ll_jobListContainer.addView(jobRowContainer); //Get the values of the Description and Price, for each row btn_JobSubmit.setOnClickListener(new View.OnClickListener() { #Override public void onClick(View v) { for (int i = 0; i < ll_jobListContainer.getChildCount(); i++) { LinearLayout currentRow = (LinearLayout)ll_jobListContainer.getChildAt(i); EditText editText = (EditText)currentRow.findViewById(R.id.description); String descriptionString = editText.getText().toString(); editText = (EditText)currentRow.findViewById(R.id.price); String priceString = editText.getText().toString(); Log.d(TAG, "z! " + descriptionString + " # " + priceString); } } }); } row_layout.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="#+id/single_row"> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="Description..." android:id="#+id/description" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="00.00" android:id="#+id/price" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#android:color/holo_red_dark" android:text="X" android:id="#+id/clear_button" /> </LinearLayout>
Android: Having trouble with newline in TextView inside BaseAdapter
Basically I am inserting text along with new line character in mysql db like this: $message = 'Hello World' . "\n"; $message .= 'This is a test' . "\n"; $message .= 'Thanks; When saving message in db, I have tried setting value of new line as \n, \\n, \\\n, \\\\n and even <br> instead of \n then used fromHtml on android app but nothing working out. In db, I can see there is new line. On Android app I want to have new line character if any showed in TextView, I have tried various things but nothing is working, I've tried things like: String message = m.getMessage().toString(); message = message.replaceAll("\\n", System.getProperty("line.separator")); Here instead of "\\n", I have also tried "\\\n", "\n" and even "\\\\n" And: Spanned html = Html.fromHtml(m.getMessage()); And: message.replaceAll("\n","<br />"); message.replaceAll("\r\n","<br />"); message.replaceAll("\r","<br />"); And: android:singleLine="false" With various things tried, in TextView I get text like these permutations: Hello WorldThis is a testThanks Hello World\This is a test\Thanks Hello World\nThis is a test\nThanks Here is my complete code: public class MessageListAdapter extends BaseAdapter { private Context context; private List<ListMessage> messagesItems; public MessageListAdapter(Context context, List<ListMessage> navDrawerItems) { this.context = context; this.messagesItems = navDrawerItems; } #Override public int getCount() { return messagesItems.size(); } #Override public Object getItem(int position) { return messagesItems.get(position); } #Override public long getItemId(int position) { return position; } #SuppressLint("InflateParams") #Override public View getView(int position, View convertView, ViewGroup parent) { /** * The following list not implemented reusable list items as list items * are showing incorrect data Add the solution if you have one * */ ListMessage m = messagesItems.get(position); LayoutInflater mInflater = (LayoutInflater) context .getSystemService(Activity.LAYOUT_INFLATER_SERVICE); // Identifying the message owner if (messagesItems.get(position).isSelf()) { // message belongs to you, so load the right aligned layout convertView = mInflater.inflate(R.layout.list_item_message_right, null); } else { // message belongs to other person, load the left aligned layout convertView = mInflater.inflate(R.layout.list_item_message_left, null); } TextView lblFrom = (TextView) convertView .findViewById(R.id.lblMsgFromListMessage); TextView lblTo = (TextView) convertView .findViewById(R.id.lblMsgToListMessage); lblFrom.setText(m.getFromName()); // Spanned html = Html.fromHtml(m.getMessage()); // String message = html.toString(); String message = m.getMessage().toString(); message = message.replaceAll("\\n", System.getProperty("line.separator")); try { lblTo.setText(message); } catch (Exception e) { lblTo.setText(message); } return convertView; } } TextView in layout: <TextView android:id="#+id/lblMsgToListMessage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="50dp" android:background="#drawable/chat_bg_msg_from" android:paddingBottom="#dimen/five_dp" android:paddingLeft="#dimen/ten_dp" android:paddingRight="#dimen/ten_dp" android:paddingTop="#dimen/five_dp" android:textColor="#color/chat_title_gray" android:textSize="#dimen/eighteen_sp" /> Is something wrong with baseAdaptor? Somewhere I saw this link, it suggested SimpleAdapter has problem setting html but in my case this doesn't help either since I am using BaseAdapter. I will be really realy thankful for your help as I have wasted five hours on this new line issue :(
Try: message = message.replaceAll("\\n", " "); or (only if there really are double backslashes in the input) message = message.replaceAll("\\n", " "); Update: Replacements were not working as the search string (\n) had been stripped out (escaped) by the sql database. This answer supplied a workaround which involves running unescape on the string prior to setting it on the TextView.
Listview only filling with first item
I have a Listview that gets its contents from an async task, but only the first item is actually getting placed into the Listview. My xml for the activity is: <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="6dp" android:layout_marginRight="6dp" android:layout_marginTop="4dp" android:layout_marginBottom="4dp" android:orientation="vertical" android:background="#drawable/bg_card"> <!-- Card Contents go here --> <TextView android:id="#+id/portfolioTitle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:ems="10" android:textSize="20sp" android:textStyle = "bold" android:text="Your Portfolio" android:padding="5dip" > </TextView> </LinearLayout > </FrameLayout> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="6dp" android:layout_marginRight="6dp" android:layout_marginTop="4dp" android:layout_marginBottom="4dp" android:orientation="vertical" android:background="#drawable/bg_card"> <!-- Card Contents go here --> <TextView android:id="#+id/sortTitle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:ems="10" android:textSize="15sp" android:textStyle = "bold" android:text="Sorting Options:" android:padding="5dip" > </TextView> <LinearLayout android:layout_height="wrap_content" android:layout_width="match_parent" android:orientation="horizontal" > <Spinner android:id="#+id/portfolioSpinner" android:layout_width="match_parent" android:layout_height="wrap_content" android:entries="#array/portfolio_array" /> </LinearLayout> </LinearLayout > </FrameLayout> <ListView android:id="#+id/allYourBeersList" android:layout_width="fill_parent" android:layout_height="fill_parent" android:dividerHeight="0px" android:divider="#null" > </ListView> </LinearLayout> </ScrollView> The async task is: public class PortfolioGetAllBeers extends AsyncTask <String, Void, String> { Context c; private ProgressDialog Dialog; public PortfolioGetAllBeers (Context context) { c = context; Dialog = new ProgressDialog(c); } #Override protected String doInBackground(String... arg0) { // TODO Auto-generated method stub return readJSONFeed(arg0[0]); } protected void onPreExecute() { Dialog.setMessage("Getting beers"); Dialog.setTitle("Loading"); Dialog.setCancelable(false); Dialog.show(); } protected void onPostExecute(String result){ //decode json here try{ JSONArray jsonArray = new JSONArray(result); //acces listview ListView lv = (ListView) ((Activity) c).findViewById(R.id.allYourBeersList); //make array list for beer final List<ShortBeerInfo> tasteList = new ArrayList<ShortBeerInfo>(); for(int i = 0; i < jsonArray.length(); i++) { String beer = jsonArray.getJSONObject(i).getString("beer"); String rate = jsonArray.getJSONObject(i).getString("rate"); String beerID = jsonArray.getJSONObject(i).getString("id"); String breweryID = jsonArray.getJSONObject(i).getString("breweryID"); int count = i + 1; beer = count + ". " + beer; //create object ShortBeerInfo tempTaste = new ShortBeerInfo(beer, rate, beerID , breweryID); //add to arraylist tasteList.add(tempTaste); //add items to listview ShortBeerInfoAdapter adapter1 = new ShortBeerInfoAdapter(c ,R.layout.brewer_stats_listview, tasteList); lv.setAdapter(adapter1); //set up clicks lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { #Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { ShortBeerInfo o=(ShortBeerInfo)arg0.getItemAtPosition(arg2); String tempID = o.id; String tempBrewID = o.brewery; Toast toast = Toast.makeText(c, tempID, Toast.LENGTH_SHORT); toast.show(); //get beer details from id Intent myIntent = new Intent(c, BeerPage2.class); myIntent.putExtra("id", tempID); myIntent.putExtra("breweryID", tempBrewID); c.startActivity(myIntent); } }); } } catch(Exception e){ } Dialog.dismiss(); } public String readJSONFeed(String URL) { StringBuilder stringBuilder = new StringBuilder(); HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(URL); try { HttpResponse response = httpClient.execute(httpGet); StatusLine statusLine = response.getStatusLine(); int statusCode = statusLine.getStatusCode(); if (statusCode == 200) { HttpEntity entity = response.getEntity(); InputStream inputStream = entity.getContent(); BufferedReader reader = new BufferedReader( new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { stringBuilder.append(line); } inputStream.close(); } else { Log.d("JSON", "Failed to download file"); } } catch (Exception e) { Log.d("readJSONFeed", e.getLocalizedMessage()); } return stringBuilder.toString(); } } Why I am confused is because my json is coming back with more then one result: [{"beer":"#9","rate":"3","id":"hB0QeO","breweryID":"qIqpZc"},{"beer":"120 Minute IPA","rate":"5","id":"EWlB8A","breweryID":"g0jHqt"},{"beer":"2011 Pere Jacques","rate":"4","id":"7EhKvb","breweryID":"APW1BC"},{"beer":"2xIPA","rate":"3","id":"kZsjqY","breweryID":"x8kqVp"},{"beer":"312 Urban Wheat Ale","rate":"3","id":"EaoR0H","breweryID":"APW1BC"},{"beer":"471 Double IPA Small Batch","rate":"4","id":"j9cp5e","breweryID":"IImUD9"},{"beer":"5 Golden Rings","rate":"2","id":"tRFIN3","breweryID":"4MVtcc"},{"beer":"60 Minute IPA","rate":"3","id":"TACnR2","breweryID":"g0jHqt"},{"beer":"75 Minute IPA","rate":"5","id":"ovCoQh","breweryID":"g0jHqt"},{"beer":"90 Minute IPA","rate":"5","id":"qqTzHb","breweryID":"g0jHqt"},{"beer":"\u00a7ucaba (Abacus)","rate":"5","id":"GWY6vH","breweryID":"qghrkC"},{"beer":"Admiral IPA","rate":"3","id":"nHYjdl","breweryID":"OYQA8m"},{"beer":"Agave Wheat","rate":"3","id":"6AcqY6","breweryID":"IImUD9"},{"beer":"Alimony Ale","rate":"0","id":"G7kmvt","breweryID":"P1I1gt"},{"beer":"Allagash Black","rate":"4","id":"z77hjQ","breweryID":"pdLPeS"},{"beer":"Allagash Dubbel","rate":"3","id":"KzHweV","breweryID":"pdLPeS"},{"beer":"Allagash Fluxus 2013","rate":"3","id":"SlMu4Q","breweryID":"pdLPeS"},{"beer":"Allagash Four","rate":"4","id":"0mttNd","breweryID":"pdLPeS"},{"beer":"Allagash Victoria Ale","rate":"4","id":"JLBMnT","breweryID":"pdLPeS"},{"beer":"Allagash White","rate":"4","id":"Q8hjek","breweryID":"pdLPeS"},{"beer":"American Amber Ale","rate":"3","id":"3SvZ4H","breweryID":"X0l98q"},{"beer":"American Pilsner","rate":"3","id":"67Hcxk","breweryID":"xcKkLh"},{"beer":"Anchor Steam","rate":"3","id":"Uiol9p","breweryID":"6PBXvz"},{"beer":"Angels Share","rate":"5","id":"ikoDPe","breweryID":"9x7wNn"},{"beer":"Aprihop","rate":"4","id":"qV0bBx","breweryID":"g0jHqt"},{"beer":"Arrogant Bastard Ale","rate":"3","id":"qlwwem","breweryID":"709vEK"},{"beer":"Aventinus Weizen-Eisbock","rate":"4","id":"avMkil","breweryID":"FQLVgV"},{"beer":"B.O.R.I.S. The Crusher Oatmeal-Imperial Stout","rate":"5","id":"Tzy7eJ","breweryID":"w5OOQ5"},{"beer":"Back in Black","rate":"3","id":"UD5Sm4","breweryID":"EdRcIs"},{"beer":"Balt Altbier","rate":"3","id":"dR7EQg","breweryID":"t6Gyij"},{"beer":"Baltic Thunder","rate":"3","id":"DCwAKJ","breweryID":"VoKbnS"},{"beer":"Bass Pale Ale","rate":"3","id":"r5GwCX","breweryID":"X2Qkw1"},{"beer":"Belgian Abbey Dubbel","rate":"3","id":"YkoqCD","breweryID":"M5zcKb"},{"beer":"Big DIPA","rate":"4","id":"aP9faI","breweryID":"wTFQaf"},{"beer":"Black & Blue","rate":"3","id":"tL3vdf","breweryID":"g0jHqt"},{"beer":"Black Cannon","rate":"3","id":"f9WbNU","breweryID":"wTFQaf"},{"beer":"Blackwing Lager","rate":"3","id":"ISXK3w","breweryID":"t6Gyij"},{"beer":"Blue Moon Belgian White","rate":"3","id":"dDXOEp","breweryID":"avMkil"},{"beer":"Br\u00e4u Weisse","rate":"4","id":"L6f8QM","breweryID":"QKdFk2"},{"beer":"Brawler","rate":"2","id":"czwGMM","breweryID":"jwWiTH"},{"beer":"Breakfast Stout","rate":"4","id":"9na4NR","breweryID":"Idm5Y5"},{"beer":"Bronx Pale Ale","rate":"4","id":"yDHpxQ","breweryID":"V0wvf7"},{"beer":"Bud Light","rate":"2","id":"dimtrs","breweryID":"BznahA"},{"beer":"Burton Baton","rate":"4","id":"em9Lxc","breweryID":"g0jHqt"},{"beer":"Caldera IPA","rate":"3","id":"kMlOin","breweryID":"iL3Juq"},{"beer":"Centennial IPA","rate":"3","id":"rAHla4","breweryID":"Idm5Y5"},{"beer":"Cerveza Sol","rate":"2","id":"4ap3mq","breweryID":"UWBCmm"},{"beer":"Chateau Jiahu","rate":"4","id":"bFOmYH","breweryID":"g0jHqt"},{"beer":"Chocolate Stout","rate":"4","id":"93XbpS","breweryID":"X0l98q"},{"beer":"Circus Boy","rate":"3","id":"JQCCB0","breweryID":"qIqpZc"},{"beer":"Corona Extra","rate":"3","id":"ujPz4L","breweryID":"wadu38"},{"beer":"Corona Light","rate":"3","id":"u7U2Ga","breweryID":"wadu38"},{"beer":"Cr\u00e8me Br\u00fbl\u00e9e Imperial Milk Stout","rate":"4","id":"Kax7jD","breweryID":"x8kqVp"},{"beer":"Cricket Hill Hopnotic","rate":"1","id":"FCGb3K","breweryID":"U0vh9j"},{"beer":"Curieux","rate":"4","id":"T6rZqg","breweryID":"pdLPeS"},{"beer":"Cutlass","rate":"3","id":"1KVlP0","breweryID":"wTFQaf"},{"beer":"Dales Pale Ale","rate":"4","id":"iT9pf4","breweryID":"q6vJUK"},{"beer":"Delirium Tremens","rate":"3","id":"siPwY9","breweryID":"8eyXN7"},{"beer":"Dogtoberfest","rate":"3","id":"IgdWNj","breweryID":"jmGoBA"},{"beer":"Don De Dieu","rate":"3","id":"i6yPHf","breweryID":"llbEuB"},{"beer":"Dos Equis Amber Lager","rate":"2","id":"s5lxSd","breweryID":"UWBCmm"},{"beer":"Double Dog Double Pale Ale","rate":"3","id":"r9nypM","breweryID":"jmGoBA"},{"beer":"Double Jack Imperial IPA","rate":"5","id":"sUL1uy","breweryID":"qghrkC"},{"beer":"Double Stout","rate":"3","id":"uVJmkY","breweryID":"c67gGy"},{"beer":"Double Wide I.P.A.","rate":"4","id":"LKzaHC","breweryID":"VDMEV7"},{"beer":"DreamWeaver Wheat Ale","rate":"3","id":"0aUaXd","breweryID":"n5QFi2"},{"beer":"Drifter Pale Ale","rate":"3","id":"HfAvcD","breweryID":"8wcv7h"},{"beer":"Duck-Rabbit Milk Stout","rate":"4","id":"C6EUeD","breweryID":"rBxNNF"},{"beer":"Duckpin Pale Ale","rate":"3","id":"17OQHF","breweryID":"t6Gyij"},{"beer":"Etrusca","rate":"4","id":"ffEc4d","breweryID":"g0jHqt"},{"beer":"Euforia Toffee Nut","rate":"4","id":"o4ENUL","breweryID":"TVgBWg"},{"beer":"Fat Tire","rate":"2","id":"tuqTtX","breweryID":"Jt43j7"},{"beer":"Festina Peche","rate":"3","id":"Gf9h6p","breweryID":"g0jHqt"},{"beer":"Finestkind IPA","rate":"3","id":"3RFxH6","breweryID":"v0MKXA"},{"beer":"Franziskaner Hefe-Weissbier Hell \/ Franziskaner C","rate":"3","id":"ZhGbaC","breweryID":"o5vGy8"},{"beer":"Furious","rate":"4","id":"qRuupG","breweryID":"cPRfoj"},{"beer":"FV13","rate":"4","id":"xv9fS8","breweryID":"pdLPeS"},{"beer":"Gemini","rate":"3","id":"L8oWyF","breweryID":"7VPQrN"},{"beer":"GKnight","rate":"3","id":"69R1Vd","breweryID":"q6vJUK"},{"beer":"Gold Ale","rate":"3","id":"bIk08d","breweryID":"wTFQaf"},{"beer":"Golden Monkey","rate":"4","id":"UfxKKB","breweryID":"VoKbnS"},{"beer":"Gonzo Imperial Porter","rate":"3","id":"kkcQtN","breweryID":"jmGoBA"},{"beer":"Guinness Draught","rate":"3","id":"StkEiv","breweryID":"HaPdSL"},{"beer":"Hardcore IPA","rate":"3","id":"7RaQWJ","breweryID":"wfAwfx"},{"beer":"Harvest","rate":"3","id":"9Pj2Cr","breweryID":"x8kqVp"},{"beer":"Harvest Moon Pumpkin Ale","rate":"3","id":"Oa5lvx","breweryID":"avMkil"},{"beer":"Heart of Darkness","rate":"3","id":"KvSwJR","breweryID":"qIqpZc"},{"beer":"Hefeweizen","rate":"3","id":"7Xn4wJ","breweryID":"P2xdU4"},{"beer":"Heifer-in-Wheat","rate":"3","id":"4MyOgi","breweryID":"REDaIN"},{"beer":"Heineken","rate":"3","id":"eGtqKZ","breweryID":"robMSl"},{"beer":"Heinnieweisse Weissebeir","rate":"3","id":"RhmCRd","breweryID":"9BPs2d"},{"beer":"Hell or High Watermelon","rate":"4","id":"VNqOKH","breweryID":"EdRcIs"},{"beer":"Helles Lager","rate":"3","id":"MSdXm6","breweryID":"D3A2mu"},{"beer":"Hellhound On My Ale","rate":"4","id":"ALDE5Q","breweryID":"g0jHqt"},{"beer":"Hellrazer","rate":"3","id":"yJ1zJK","breweryID":"TVgBWg"},{"beer":"Hennepin Saison Ale","rate":"4","id":"RsXBB4","breweryID":"tCxPtR"},{"beer":"Hercules Double IPA","rate":"4","id":"xHovlT","breweryID":"I8WZv2"},{"beer":"Honey Weiss","rate":"3","id":"YgHnZO","breweryID":"ZDghkK"},{"beer":"Honker's Ale","rate":"3","id":"TEG3J9","breweryID":"APW1BC"},{"beer":"Hop Heathen Imperial Black Ale","rate":"3","id":"bMXin5","breweryID":"w5OOQ5"},{"beer":"Hop Stoopid","rate":"3","id":"Pni8Jo","breweryID":"nLsoQ9"},{"beer":"Hop Wallop","rate":"3","id":"b58sGA","breweryID":"VoKbnS"},{"beer":"HopDevil","rate":"3","id":"IzTjAm","breweryID":"VoKbnS"},{"beer":"Hopfen-Weisse","rate":"5","id":"wXHOmA","breweryID":"FQLVgV"},{"beer":"Hops Infusion","rate":"3","id":"6nkcOK","breweryID":"a57dkm"},{"beer":"Hopsecutioner","rate":"4","id":"Rfe5aM","breweryID":"DPLTAJ"},{"beer":"Hoptober","rate":"3","id":"n1bFMy","breweryID":"Jt43j7"},{"beer":"Horseshoe Bend Pale Ale","rate":"3","id":"Uvuoay","breweryID":"xcKkLh"},{"beer":"Illinois","rate":"3","id":"PZbw01","breweryID":"APW1BC"},{"beer":"Imperial IPA","rate":"3","id":"WT6hkF","breweryID":"TR98tr"},{"beer":"Imperial Pumpkin Ale","rate":"4","id":"LRCEhC","breweryID":"a57dkm"},{"beer":"Imperial Russian Stout","rate":"0","id":"pD5RiK","breweryID":"709vEK"},{"beer":"Imperial Stout","rate":"4","id":"IqPdv8","breweryID":"Idm5Y5"},{"beer":"India Pale Ale","rate":"3","id":"fu2qgB","breweryID":"APW1BC"},{"beer":"Indian Brown Ale","rate":"3","id":"AZI8ib","breweryID":"g0jHqt"},{"beer":"International Arms Race","rate":"2","id":"aX0e6r","breweryID":"jmGoBA"},{"beer":"IPA","rate":"3","id":"iLlMCb","breweryID":"nLsoQ9"},{"beer":"Italian Strong Ale","rate":"5","id":"9S5ObB","breweryID":"wAdTKf"},{"beer":"Judgement Day","rate":"3","id":"Gwo4rP","breweryID":"9x7wNn"},{"beer":"Just the Tip","rate":"3","id":"ekhzhU","breweryID":"rKXfsB"},{"beer":"Kellerweis","rate":"3","id":"JVv3qI","breweryID":"nHLlnK"},{"beer":"Killian's Irish Red","rate":"3","id":"FXGCOG","breweryID":"avMkil"},{"beer":"La Torpille","rate":"3","id":"gghCq9","breweryID":"6DG1qh"},{"beer":"Lancaster Milk Stout","rate":"3","id":"aZtMd7","breweryID":"VGDfKl"},{"beer":"Little Sumpin' Sumpin'","rate":"4","id":"svXHfu","breweryID":"nLsoQ9"},{"beer":"Local 2","rate":"3","id":"vpdrzj","breweryID":"4OBVPn"},{"beer":"Loose Cannon","rate":"3","id":"Bt79WS","breweryID":"wTFQaf"},{"beer":"Lucky 13","rate":"3","id":"CWwxeR","breweryID":"nLsoQ9"},{"beer":"Lucky 7 Porter","rate":"3","id":"a6XiKI","breweryID":"Ysh6PO"},{"beer":"M\u00e4rzen","rate":"4","id":"zomWCT","breweryID":"P2xdU4"},{"beer":"M\u00fcnchner Sommer","rate":"5","id":"TbP3By","breweryID":"4rlPFf"},{"beer":"Mad Elf Ale","rate":"4","id":"ZRzruY","breweryID":"n5QFi2"},{"beer":"Mad King\u2019s Weiss","rate":"3","id":"5JQA4h","breweryID":"VoKbnS"},{"beer":"Mana Wheat","rate":"3","id":"fem70X","breweryID":"fwCFE4"},{"beer":"Matilda","rate":"5","id":"uKquc0","breweryID":"APW1BC"},{"beer":"Maui Coconut Porter","rate":"3","id":"sNQLDD","breweryID":"fwCFE4"},{"beer":"Merry Monks","rate":"3","id":"gz4uZ6","breweryID":"a57dkm"},{"beer":"Midas Touch","rate":"5","id":"YFZKZA","breweryID":"g0jHqt"},{"beer":"Midshipman Mild","rate":"3","id":"eEjA64","breweryID":"OYQA8m"},{"beer":"Mild Winter","rate":"3","id":"hrhfc1","breweryID":"APW1BC"},{"beer":"Milk Stout Nitro","rate":"3","id":"gtaIQr","breweryID":"Ro08YF"},{"beer":"Miller Lite","rate":"1","id":"KJIjyd","breweryID":"MWi5Kp"},{"beer":"Mischief","rate":"3","id":"5A7pI0","breweryID":"4MVtcc"},{"beer":"Misery Bay IPA","rate":"2","id":"uSxQME","breweryID":"LHQ79n"},{"beer":"Mongo Double IPA","rate":"4","id":"9tIw2j","breweryID":"ayEBYP"},{"beer":"Monumental IPA","rate":"3","id":"kckAgC","breweryID":"9FwufS"},{"beer":"Moo Thunder Stout","rate":"3","id":"D4Ka8l","breweryID":"9BPs2d"},{"beer":"Moonglow Weizenbock","rate":"4","id":"DOrgPb","breweryID":"VoKbnS"},{"beer":"My Antonia","rate":"3","id":"OyeqOI","breweryID":"g0jHqt"},{"beer":"Namaste","rate":"3","id":"1INeXj","breweryID":"g0jHqt"},{"beer":"Narragansett Lager","rate":"2","id":"lBKttb","breweryID":"mGqkXE"},{"beer":"National Bohemian","rate":"2","id":"ssQJcb","breweryID":"AKyyYN"},{"beer":"Newcastle Werewolf","rate":"2","id":"xzED0r","breweryID":"Qutakc"},{"beer":"Noble Rot","rate":"4","id":"tEpzX3","breweryID":"g0jHqt"},{"beer":"Nommo Dubbel","rate":"3","id":"WzJmsi","breweryID":"VDMEV7"},{"beer":"Nugget Nectar","rate":"3","id":"x8H3l7","breweryID":"n5QFi2"},{"beer":"Oak Barrel Stout","rate":"3","id":"JdJXIl","breweryID":"xG9JyI"},{"beer":"Oat Imperial Oatmeal Stout","rate":"4","id":"1UmxNj","breweryID":"x8kqVp"},{"beer":"Old Chub","rate":"3","id":"KmsdoV","breweryID":"q6vJUK"},{"beer":"Old Guardian Oak-Smoked","rate":"4","id":"Pwkvsq","breweryID":"709vEK"},{"beer":"Old Man Winter","rate":"3","id":"X60E3Q","breweryID":"x8kqVp"},{"beer":"Old Pro","rate":"4","id":"SS2uWf","breweryID":"t6Gyij"},{"beer":"Old Rasputin","rate":"4","id":"CfJ0cK","breweryID":"yLBNrD"},{"beer":"Old Ruffian","rate":"3","id":"AqEUBQ","breweryID":"I8WZv2"},{"beer":"Old Scratch Amber Lager","rate":"4","id":"N4LF2o","breweryID":"jmGoBA"},{"beer":"Olde School Barleywine","rate":"5","id":"YDBgUE","breweryID":"g0jHqt"},{"beer":"Ommegang Abbey Ale","rate":"4","id":"jYBtXz","breweryID":"tCxPtR"},{"beer":"Ommegang BPA","rate":"3","id":"N101SS","breweryID":"tCxPtR"},{"beer":"Otis","rate":"2","id":"uTPvQK","breweryID":"7VPQrN"},{"beer":"Ozzy","rate":"4","id":"3te24V","breweryID":"YytkpO"},{"beer":"Pabst Blue Ribbon","rate":"2","id":"pDKyvz","breweryID":"AKyyYN"},{"beer":"Pale Ale","rate":"3","id":"cdkpyx","breweryID":"nHLlnK"},{"beer":"Palo Santo Marron","rate":"5","id":"7LrYr1","breweryID":"g0jHqt"},{"beer":"Pangaea","rate":"4","id":"Oq4XtM","breweryID":"g0jHqt"},{"beer":"Pearl Jam Twenty Faithful Ale","rate":"3","id":"6IjMIK","breweryID":"g0jHqt"},{"beer":"Peeper","rate":"3","id":"KdKlo9","breweryID":"xgrmyW"},{"beer":"Phin ","rate":"3","id":"cWMMWU","breweryID":"x8kqVp"},{"beer":"Porter","rate":"3","id":"bZub8V","breweryID":"9FwufS"},{"beer":"Porter Pounder","rate":"3","id":"h5zbGr","breweryID":"pqSkmD"},{"beer":"Positive Contact","rate":"3","id":"eAvRRc","breweryID":"g0jHqt"},{"beer":"Powder Monkey","rate":"2","id":"PbHXnC","breweryID":"OYQA8m"},{"beer":"Pumkin Ale","rate":"4","id":"zpyLEw","breweryID":"tNDKBY"},{"beer":"Pumking","rate":"4","id":"iHEJZm","breweryID":"x8kqVp"},{"beer":"Pumpkin Ale","rate":"3","id":"yu0Mbf","breweryID":"v0MKXA"},{"beer":"Pumpkinhead Ale","rate":"3","id":"TlBAjN","breweryID":"5N0usi"},{"beer":"Punkin Ale","rate":"4","id":"hGjIJg","breweryID":"g0jHqt"},{"beer":"Racer 5 IPA","rate":"3","id":"o1OELJ","breweryID":"5tw2Iw"},{"beer":"Raging Bitch Belgian IPA","rate":"4","id":"P203ye","breweryID":"jmGoBA"},{"beer":"Raison DEtre","rate":"3","id":"Q4Ah1v","breweryID":"g0jHqt"},{"beer":"Ranger","rate":"3","id":"iaYJ7X","breweryID":"Jt43j7"},{"beer":"Rare Vos","rate":"3","id":"OMyQoC","breweryID":"tCxPtR"},{"beer":"Rayon Vert","rate":"4","id":"vMm0Rc","breweryID":"Nj8cgD"},{"beer":"Red Sky at Night","rate":"3","id":"QWYlpK","breweryID":"wTFQaf"},{"beer":"Reds Rye PA","rate":"3","id":"FOC78c","breweryID":"Idm5Y5"},{"beer":"Robust Porter","rate":"4","id":"fkylQX","breweryID":"v0MKXA"},{"beer":"Ruination IPA","rate":"4","id":"7cnuJq","breweryID":"709vEK"},{"beer":"Sah'tea","rate":"4","id":"dc6ShA","breweryID":"g0jHqt"},{"beer":"Saison du BUFF","rate":"3","id":"CTbk45","breweryID":"g0jHqt"},{"beer":"Saison Rue","rate":"4","id":"V0T8uP","breweryID":"4MVtcc"},{"beer":"Samuel Adams Boston Lager","rate":"3","id":"z4k3eU","breweryID":"1wSztN"},{"beer":"Samuel Adams Octoberfest","rate":"3","id":"Hyyhug","breweryID":"1wSztN"},{"beer":"Samuel Adams Summer Ale","rate":"3","id":"DiBfxM","breweryID":"1wSztN"},{"beer":"Samuel Adams Winter Lager","rate":"2","id":"4fM6Pf","breweryID":"1wSztN"},{"beer":"Sapporo Premium Beer","rate":"2","id":"TOHi4D","breweryID":"D61TcY"},{"beer":"Schwartz Bier","rate":"3","id":"y4THvR","breweryID":"iw1hDB"},{"beer":"Shock Top","rate":"2","id":"v7H1Ev","breweryID":"BznahA"},{"beer":"Sixty-One","rate":"4","id":"L1eJ2p","breweryID":"g0jHqt"},{"beer":"Small Craft Warning","rate":"3","id":"2qHZyl","breweryID":"wTFQaf"},{"beer":"Smoking Wood","rate":"5","id":"8NX7Sy","breweryID":"4MVtcc"},{"beer":"Snake Dog","rate":"3","id":"Blig3z","breweryID":"jmGoBA"},{"beer":"Snow Pants","rate":"4","id":"g8oVuV","breweryID":"t6Gyij"},{"beer":"Sofie","rate":"4","id":"KBQTlS","breweryID":"APW1BC"},{"beer":"Son of a Peach","rate":"4","id":"94Fe7D","breweryID":"bWL816"},{"beer":"Squall IPA","rate":"4","id":"LZmXC8","breweryID":"g0jHqt"},{"beer":"Stella Artois","rate":"3","id":"Jc7iGI","breweryID":"mIWMKP"},{"beer":"Stone IPA","rate":"3","id":"PAM6wX","breweryID":"709vEK"},{"beer":"Stone Levitation Ale","rate":"4","id":"OaZYgf","breweryID":"709vEK"},{"beer":"Storm King Imperial Stout","rate":"4","id":"4M26ru","breweryID":"VoKbnS"},{"beer":"Sublimely Self-Righteous Ale","rate":"4","id":"SAtbDP","breweryID":"709vEK"},{"beer":"Summer Love Ale","rate":"3","id":"SzhLvG","breweryID":"VoKbnS"},{"beer":"Summer Shandy","rate":"2","id":"nJjPsG","breweryID":"ZDghkK"},{"beer":"Summertime","rate":"3","id":"tXTETf","breweryID":"APW1BC"},{"beer":"Sunset Amber Ale","rate":"4","id":"scC0RX","breweryID":"xcKkLh"},{"beer":"Sweet Baby Jesus!","rate":"4","id":"opSf4n","breweryID":"TVgBWg"},{"beer":"Sweet Child of Vine","rate":"3","id":"xrLwng","breweryID":"5GoGSi"},{"beer":"ta henket","rate":"4","id":"icSARl","breweryID":"g0jHqt"},{"beer":"Tank 7 Farmhouse Ale","rate":"3","id":"lDiXyX","breweryID":"VDMEV7"},{"beer":"Ten Fidy","rate":"5","id":"x6bRxw","breweryID":"q6vJUK"},{"beer":"The Cask","rate":"3","id":"NgxwRi","breweryID":"dwroV3"},{"beer":"The Fear","rate":"2","id":"0ZX12D","breweryID":"jmGoBA"},{"beer":"The Libertine","rate":"4","id":"irF7Mh","breweryID":"5GoGSi"},{"beer":"The Sixth Glass","rate":"4","id":"zrAAHP","breweryID":"VDMEV7"},{"beer":"The Truth","rate":"3","id":"o9TSOv","breweryID":"jmGoBA"},{"beer":"The Vermonster","rate":"2","id":"UJI7C4","breweryID":"LpX3cU"},{"beer":"Theobroma","rate":"0","id":"H1L7UE","breweryID":"g0jHqt"},{"beer":"Third Shift","rate":"3","id":"g284jn","breweryID":"avMkil"},{"beer":"Thomas Jefferson's Tavern Ale","rate":"3","id":"xDzvQP","breweryID":"jwWiTH"},{"beer":"Three Philosophers","rate":"4","id":"TOzkLy","breweryID":"tCxPtR"},{"beer":"Torpedo Extra IPA","rate":"3","id":"JaS6T7","breweryID":"nHLlnK"},{"beer":"Trade Winds Tripel","rate":"4","id":"jdulDH","breweryID":"4MVtcc"},{"beer":"Tribute Tripel","rate":"5","id":"FdRZ7e","breweryID":"UbQHhM"},{"beer":"Troegenator Double Bock","rate":"3","id":"OGlmOC","breweryID":"n5QFi2"},{"beer":"Tweasonale","rate":"3","id":"Qx1hbt","breweryID":"g0jHqt"},{"beer":"UFO White","rate":"3","id":"cG83LQ","breweryID":"RzvedX"},{"beer":"Unfiltered Wheat Beer","rate":"3","id":"lgaPWe","breweryID":"VDMEV7"},{"beer":"Unibroue 17","rate":"4","id":"VfyYpZ","breweryID":"llbEuB"},{"beer":"Urkontinent","rate":"3","id":"XQyXhk","breweryID":"g0jHqt"},{"beer":"Vanilla Porter","rate":"3","id":"Bk34Go","breweryID":"IImUD9"},{"beer":"Vanilla Stout","rate":"4","id":"NRhCm4","breweryID":"oBe8dQ"},{"beer":"Walkers Reserve","rate":"3","id":"JgdTCV","breweryID":"qghrkC"},{"beer":"Wells Banana Bread Beer","rate":"4","id":"hQzCbn","breweryID":"6oEP92"},{"beer":"West Coast IPA","rate":"4","id":"RC4BkU","breweryID":"Nj8cgD"},{"beer":"Western Rider","rate":"2","id":"ymabSa","breweryID":"bRKIdZ"},{"beer":"Winter Storm - Category 5 Ale","rate":"3","id":"fA0O8C","breweryID":"wTFQaf"},{"beer":"Wookey Jack","rate":"3","id":"f5DoHi","breweryID":"qghrkC"},{"beer":"World Wide Stout","rate":"4","id":"H5sA73","breweryID":"g0jHqt"},{"beer":"Yakima Glory Ale","rate":"3","id":"q7dLm5","breweryID":"VoKbnS"},{"beer":"Yeti Imperial Stout","rate":"5","id":"oz1oll","breweryID":"I8WZv2"},{"beer":"Yuengling Traditional Lager","rate":"3","id":"wd1Y84","breweryID":"pX8lES"}] Adapter code: public class ShortBeerInfoAdapter extends ArrayAdapter<ShortBeerInfo>{ Context context; int layoutResourceId; List<ShortBeerInfo> data = null; public ShortBeerInfoAdapter(Context context, int layoutResourceId, List<ShortBeerInfo> data) { super(context, layoutResourceId, data); this.layoutResourceId = layoutResourceId; this.context = context; this.data = data; } #Override public View getView(int position, View convertView, ViewGroup parent) { View row = convertView; beerHolder holder = null; if(row == null) { LayoutInflater inflater = ((Activity)context).getLayoutInflater(); row = inflater.inflate(layoutResourceId, parent, false); holder = new beerHolder(); holder.txtBeer = (TextView)row.findViewById(R.id.breweryName); holder.txtRate = (TextView)row.findViewById(R.id.breweryRate); holder.txtBar = (RatingBar) row.findViewById(R.id.starbar); row.setTag(holder); } else { holder = (beerHolder)row.getTag(); } ShortBeerInfo beer = data.get(position); holder.txtBeer.setText(beer.beer); holder.txtRate.setText(beer.rate + " out of 5.00 Stars"); holder.numHolder= Float.parseFloat(beer.rate); holder.txtBar.setNumStars(5); holder.txtBar.setRating(holder.numHolder); return row; } static class beerHolder { TextView txtBeer; TextView txtRate; RatingBar txtBar; Float numHolder; } }
I think you can't see the list properly because your ListVew is within a ScrollView. ListView itself is scrollable , so it doesn't show properly in a ScrollView , you can at most see a ListView with very small height that fits one or two elements. Try using your ListView outside of ScrollView to test whether your code is correct or not. Hope it helps.
The short answer is that your doing it wrong. You should be asynchronously loading the data into a sqlite db table and using a Loader with a cursor adapter. Also, even using the code you have (and its hard to read from my phone here) it looks like your only adding one element to the list before you add the list adapter to the list view, which would be why you are only seeing a single item. Another thing that may be causing you trouble is that you're asynchronously loading the data into a list view that has been created but you don't seem signal that the adapter has new data as the task finishes.
Move your code for the adapter so that it is outside and below your for loop. You are creating a new adapter for every iteration and it is probably running really slow because of it. Also you are setting your onitemclicklistener for every iteration too. It only needs to be done one time. Do that and then see what happens. Also put a breakpoint after the for loop and see how many items are in your tasteList. If there is more than one then your adapter is most likely the problem. If you can post your code for your adapter. I guess my answer is that you probably aren't returning back more than one item. Since the adapter is posting data to the list it should be ok. Once you can debug the app and see how many items are returning then we can know for sure.
Creating a New Button in existing Source Code? [closed]
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center. Closed 9 years ago. http://www.itechcode.com/2012/03/18/create-calculator-in-android-programming/ Im using his source code but it seems very different than the "Beginner Level" Programming I have been use to i.e. creating new project, modifying layout, referencing in main.java, etc. I'm trying to use his source code and modify/create new operations and maybe add a activity. I would usually know how to do most of that stuff if it wasn't laid out differently. Thank You! package com.pragmatouch.calculator; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Iterator; import java.util.Stack; import android.app.Activity; import android.os.Bundle; import android.widget.AdapterView; import android.widget.Button; import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; import android.widget.GridView; import android.view.View; import android.view.View.OnClickListener; public class main extends Activity { GridView mKeypadGrid; TextView userInputText; TextView memoryStatText; Stack<String> mInputStack; Stack<String> mOperationStack; KeypadAdapter mKeypadAdapter; TextView mStackText; boolean resetInput = false; boolean hasFinalResult = false; String mDecimalSeperator; double memoryValue = Double.NaN; /** Called when the activity is first created. */ #Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); DecimalFormat currencyFormatter = (DecimalFormat) NumberFormat .getInstance(); char decimalSeperator = currencyFormatter.getDecimalFormatSymbols() .getDecimalSeparator(); mDecimalSeperator = Character.toString(decimalSeperator); setContentView(R.layout.main); // Create the stack mInputStack = new Stack<String>(); mOperationStack = new Stack<String>(); // Get reference to the keypad button GridView mKeypadGrid = (GridView) findViewById(R.id.grdButtons); // Get reference to the user input TextView userInputText = (TextView) findViewById(R.id.txtInput); userInputText.setText("0"); memoryStatText = (TextView) findViewById(R.id.txtMemory); memoryStatText.setText(""); mStackText = (TextView) findViewById(R.id.txtStack); // Create Keypad Adapter mKeypadAdapter = new KeypadAdapter(this); // Set adapter of the keypad grid mKeypadGrid.setAdapter(mKeypadAdapter); // Set button click listener of the keypad adapter mKeypadAdapter.setOnButtonClickListener(new OnClickListener() { #Override public void onClick(View v) { Button btn = (Button) v; // Get the KeypadButton value which is used to identify the // keypad button from the Button's tag KeypadButton keypadButton = (KeypadButton) btn.getTag(); // Process keypad button ProcessKeypadInput(keypadButton); } }); mKeypadGrid.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View v, int position, long id) { } }); } private void ProcessKeypadInput(KeypadButton keypadButton) { //Toast.makeText(this, keypadButton.getText(), Toast.LENGTH_SHORT).show(); String text = keypadButton.getText().toString(); String currentInput = userInputText.getText().toString(); int currentInputLen = currentInput.length(); String evalResult = null; double userInputValue = Double.NaN; switch (keypadButton) { case BACKSPACE: // Handle backspace // If has operand skip backspace if (resetInput) return; int endIndex = currentInputLen - 1; // There is one character at input so reset input to 0 if (endIndex < 1) { userInputText.setText("0"); } // Trim last character of the input text else { userInputText.setText(currentInput.subSequence(0, endIndex)); } break; case SIGN: // Handle -/+ sign // input has text and is different than initial value 0 if (currentInputLen > 0 && currentInput != "0") { // Already has (-) sign. Remove that sign if (currentInput.charAt(0) == '-') { userInputText.setText(currentInput.subSequence(1, currentInputLen)); } // Prepend (-) sign else { userInputText.setText("-" + currentInput.toString()); } } break; case CE: // Handle clear input userInputText.setText("0"); break; case C: // Handle clear input and stack userInputText.setText("0"); clearStacks(); break; case DECIMAL_SEP: // Handle decimal seperator if (hasFinalResult || resetInput) { userInputText.setText("0" + mDecimalSeperator); hasFinalResult = false; resetInput = false; } else if (currentInput.contains(".")) return; else userInputText.append(mDecimalSeperator); break; case DIV: case PLUS: case MINUS: case MULTIPLY: if (resetInput) { mInputStack.pop(); mOperationStack.pop(); } else { if (currentInput.charAt(0) == '-') { mInputStack.add("(" + currentInput + ")"); } else { mInputStack.add(currentInput); } mOperationStack.add(currentInput); } mInputStack.add(text); mOperationStack.add(text); dumpInputStack(); evalResult = evaluateResult(false); if (evalResult != null) userInputText.setText(evalResult); resetInput = true; break; case CALCULATE: if (mOperationStack.size() == 0) break; mOperationStack.add(currentInput); evalResult = evaluateResult(true); if (evalResult != null) { clearStacks(); userInputText.setText(evalResult); resetInput = false; hasFinalResult = true; } break; case M_ADD: // Add user input value to memory buffer userInputValue = tryParseUserInput(); if (Double.isNaN(userInputValue)) return; if (Double.isNaN(memoryValue)) memoryValue = 0; memoryValue += userInputValue; displayMemoryStat(); hasFinalResult = true; break; case M_REMOVE: // Subtract user input value to memory buffer userInputValue = tryParseUserInput(); if (Double.isNaN(userInputValue)) return; if (Double.isNaN(memoryValue)) memoryValue = 0; memoryValue -= userInputValue; displayMemoryStat(); hasFinalResult = true; break; case MC: // Reset memory buffer to 0 memoryValue = Double.NaN; displayMemoryStat(); break; case MR: // Read memoryBuffer value if (Double.isNaN(memoryValue)) return; userInputText.setText(doubleToString(memoryValue)); displayMemoryStat(); break; case MS: // Set memoryBuffer value to user input userInputValue = tryParseUserInput(); if (Double.isNaN(userInputValue)) return; memoryValue = userInputValue; displayMemoryStat(); hasFinalResult = true; break; case PRGM: break; default: if (Character.isDigit(text.charAt(0))) { if (currentInput.equals("0") || resetInput || hasFinalResult) { userInputText.setText(text); resetInput = false; hasFinalResult = false; } else { userInputText.append(text); resetInput = false; } } break; } } private void clearStacks() { mInputStack.clear(); mOperationStack.clear(); mStackText.setText(""); } private void dumpInputStack() { Iterator<String> it = mInputStack.iterator(); StringBuilder sb = new StringBuilder(); while (it.hasNext()) { CharSequence iValue = it.next(); sb.append(iValue); } mStackText.setText(sb.toString()); } private String evaluateResult(boolean requestedByUser) { if ((!requestedByUser && mOperationStack.size() != 4) || (requestedByUser && mOperationStack.size() != 3)) return null; String left = mOperationStack.get(0); String operator = mOperationStack.get(1); String right = mOperationStack.get(2); String tmp = null; if (!requestedByUser) tmp = mOperationStack.get(3); double leftVal = Double.parseDouble(left.toString()); double rightVal = Double.parseDouble(right.toString()); double result = Double.NaN; if (operator.equals(KeypadButton.DIV.getText())) { result = leftVal / rightVal; } else if (operator.equals(KeypadButton.MULTIPLY.getText())) { result = leftVal * rightVal; } else if (operator.equals(KeypadButton.PLUS.getText())) { result = leftVal + rightVal; } else if (operator.equals(KeypadButton.MINUS.getText())) { result = leftVal - rightVal; } String resultStr = doubleToString(result); if (resultStr == null) return null; mOperationStack.clear(); if (!requestedByUser) { mOperationStack.add(resultStr); mOperationStack.add(tmp); } return resultStr; } private String doubleToString(double value) { if (Double.isNaN(value)) return null; long longVal = (long) value; if (longVal == value) return Long.toString(longVal); else return Double.toString(value); } private double tryParseUserInput() { String inputStr = userInputText.getText().toString(); double result = Double.NaN; try { result = Double.parseDouble(inputStr); } catch (NumberFormatException nfe) { } return result; } private void displayMemoryStat() { if (Double.isNaN(memoryValue)) { memoryStatText.setText(""); } else { memoryStatText.setText("M = " + doubleToString(memoryValue)); } } } ENUM: package com.pragmatouch.calculator; public enum KeypadButton { MC("MC",KeypadButtonCategory.MEMORYBUFFER) , MR("MR",KeypadButtonCategory.MEMORYBUFFER) , MS("MS",KeypadButtonCategory.MEMORYBUFFER) , M_ADD("M+",KeypadButtonCategory.MEMORYBUFFER) , M_REMOVE("M-",KeypadButtonCategory.MEMORYBUFFER) , BACKSPACE("<-",KeypadButtonCategory.CLEAR) , CE("CE",KeypadButtonCategory.CLEAR) , C("C",KeypadButtonCategory.CLEAR) , ZERO("0",KeypadButtonCategory.NUMBER) , ONE("1",KeypadButtonCategory.NUMBER) , TWO("2",KeypadButtonCategory.NUMBER) , THREE("3",KeypadButtonCategory.NUMBER) , FOUR("4",KeypadButtonCategory.NUMBER) , FIVE("5",KeypadButtonCategory.NUMBER) , SIX("6",KeypadButtonCategory.NUMBER) , SEVEN("7",KeypadButtonCategory.NUMBER) , EIGHT("8",KeypadButtonCategory.NUMBER) , NINE("9",KeypadButtonCategory.NUMBER) , PLUS(" + ",KeypadButtonCategory.OPERATOR) , MINUS(" - ",KeypadButtonCategory.OPERATOR) , MULTIPLY(" * ",KeypadButtonCategory.OPERATOR) , DIV(" / ",KeypadButtonCategory.OPERATOR) , RECIPROC("1/x",KeypadButtonCategory.OTHER) , DECIMAL_SEP(",",KeypadButtonCategory.OTHER) , SIGN("±",KeypadButtonCategory.OTHER) , SQRT("SQRT",KeypadButtonCategory.OTHER) , PERCENT("%",KeypadButtonCategory.OTHER) , CALCULATE("=",KeypadButtonCategory.RESULT) , PRGM("PRGM",KeypadButtonCategory.PRGM) , DUMMY("",KeypadButtonCategory.DUMMY); CharSequence mText; // Display Text KeypadButtonCategory mCategory; KeypadButton(CharSequence text,KeypadButtonCategory category) { mText = text; mCategory = category; } public CharSequence getText() { return mText; } } package com.pragmatouch.calculator; public enum KeypadButtonCategory { MEMORYBUFFER , NUMBER , OPERATOR , DUMMY , CLEAR , RESULT , OTHER , PRGM }
I have a great answer for you. I recently wanted to create my own button in android but I wanted to do it in a simple way. Follow these steps and in a few minutes I will post pictures. 1) create a new layout. start with a LinearLayout. Nest a FramedLayout and another LinearLayout inside of it. 2) then add a TextView to it. This is where practice makes perfect. Play around with the attributes. Learn what they do. when you have the general information of how you want your button to be display go to the next step. 3) what your are going to do is include this in another view as a button. You can use a specific attribute to make it look like a button as well. Give me a few minutes and I will post some code and a picture. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="#+id/CBN_LinearLayout" style="#android:style/Widget.Button" android:layout_width="match_parent" android:layout_height="50dp" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="#+id/CBV_texview1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginRight="10dp" android:layout_weight="1" android:gravity="right" android:text="#string/checkorder" android:textColor="#color/Black" /> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_weight="1" > <ImageView android:id="#+id/CBV_imageView1" android:layout_width="23dp" android:layout_height="15dp" android:layout_gravity="center_vertical" android:contentDescription="#string/redcirclenotify" android:src="#drawable/rednotify" android:visibility="visible" /> <TextView android:id="#+id/CBV_textview2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="8dp" android:gravity="left" android:text="#string/zero" android:visibility="visible" /> </FrameLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="#+id/CBV_textview3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:fadingEdge="horizontal" android:gravity="center_horizontal" android:text="#string/blankstring" /> <TextView android:id="#+id/CBV_textview4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_horizontal" android:text="#string/blankstring" /> </LinearLayout> when you add it to another view as a button you use: <include android:id="#+id/MI_checkorder" style="android:buttonStyle" android:layout_width="wrap_content" android:layout_height="50dp" android:layout_gravity="bottom" android:layout_marginTop="5dp" android:layout_weight="1" layout="#layout/custombtnview" android:background="#style/AppTheme" android:clickable="true" android:focusable="true" /> The important part of this is setting the Style for the root LinearLayout to #android:style/Widget.Button Once this is done it will look like a button and work like a button. Below is an image of the final product: another part of your question. Adjust sizes of standard buttons in android: 1) almost everything can be controled with how you use the XML. This can all be controled in the area to right, in the ADK. These attributes help you to control almost every aspect. for example as in the calculator... you have 4 buttons in a row so you want to add 4 buttons inside of a horizontal LinearLayout. Then you can give the a weight of 1 for each button then set their Width to FillParent. This will auto size the buttons to be displayed in the width of the screen equally. Am I better off making my own calc or modify the existing code? I would never tell someone to recreate the wheel, however, if you do not understand the code well enough to pickup where they left off then this can be an uphill struggle for you. Your best bet if you are having trouble understanding the code given to you or how to modify it, would be to actually post the code in another question and be very specific and ask for example how can I change what this particular button displays and what the result of clicking it would be. This forum depends on the people asking the questions to be clear and concise. If not then questions will closed as fast as they are opened. Generalizations are severely frowned upon on the site. In the end, what I am trying to do is make my own scientific calculator but I don't want to spend extra time doing the simple operations. The best way to answer this is to take a look at how the calculator is assembled in the GUI or Graphical Layout. Try changing a button and what it does. for example make the plus a minus just for the learning curve. 1) look for , PLUS(" + ",KeypadButtonCategory.OPERATOR) and notice that is a string for plus. change it to " T " see if it changes in the app. If it does then go into the code. In the code you will find case CALCULATE: for for the = sign in the ENUM and then inside that you find evalResult = evaluateResult(true);. If you follow this you reach: if (operator.equals(KeypadButton.DIV.getText())) { result = leftVal / rightVal; } else if (operator.equals(KeypadButton.MULTIPLY.getText())) { result = leftVal * rightVal; } else if (operator.equals(KeypadButton.PLUS.getText())) { result = leftVal + rightVal; } else if (operator.equals(KeypadButton.MINUS.getText())) { result = leftVal - rightVal; } so now you can change result = leftVal + rightVal; to result = leftVal - rightVal; and you have just changed it. so it will take some time to understand the code but you have to do some trial and error to understand it. I hope this helps answer your question.