So in my application I am using a ListView to display data from an ArrayList which holds objects. The data is displayed using the same method as the tutorial on the android developer website:
// automatically adds a ListView to fill the entire screen of this activity
setListAdapter(new ArrayAdapter<Part>(this, R.layout.list_item, Main.parts));
ListView lv = getListView();
// allows the user to start typing to filter the list
lv.setTextFilterEnabled(true);
// set the click listener for each list item
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast.makeText(getApplicationContext(), ((TextView) view).getText(), Toast.LENGTH_SHORT).show();
}
});
The objects are currently displayed in each list_item:
<!-- Defines the layout for each item being placed in the ListView. -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp" >
</TextView>
So I return each object as such:
public String toString() {
return "Item Number: " + itemNmbr + "\nPrice: " + price + "\nDescription: " + desc;
}
An example of how the list currently looks:
http://imageshack.us/photo/my-images/689/devicet.png/
The problem is, I need to format the title separately from the data. (because it needs to be bold, and possibly spaced out a little further.)
Any ideas? I'm currently testing on how to get two textviews to work together.
Thank you!
I would recommend using a custom adapter extending BaseAdapter.
http://developer.android.com/reference/android/widget/BaseAdapter.html
See this link for an example.
http://www.softwarepassion.com/android-series-custom-listview-items-and-adapters/
Related
I'm trying to make a very very simple spinner at least, as follows:
XML:
<Spinner
android:id="#+id/spinner_categories"
android:layout_width="0sp"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:layout_weight="1"
android:textColor="#000000"
android:spinnerMode="dropdown"/>
JAVA:
spinnerCategories = findViewById(R.id.spinner_categories);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
getApplicationContext(),
android.R.layout.simple_spinner_item,
categories);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerCategories.setAdapter(adapter);
Log.d(Utilities.LOG_FLAG, "SPINNER: " + spinnerCategories.toString());
spinnerCategories.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
Toast.makeText(context, categories.get(position).toString(), Toast.LENGTH_SHORT).show();
Log.d(Utilities.LOG_FLAG, "SELECTED");
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
Log.d(Utilities.LOG_FLAG, " NOT SELECTED");
}
});
I can see the entire list, but once I click on an item, nothing happans, and it wont show the selection at all, even if I use setSelection(), and if I try to do spinnerCategories.getSelectedItem().toString() I get a NullPointerException.
I tried searching the web a lot, but none solution seems to help me...
Edit
For some reason when I load the page and then I go out of the page and reenter it, only then it will show the selected items of the spinner
On the first load it shows for a very brief second and then it's gone until the page is reentered the second time
The setOnItemSelectedListener gets triggered when you click on an element from the drop down menu .. to fetch the selected item you need to use .getSelectedItemPosition() something like
categoriesList.get(spinner.getSelectedItemPosition)
I'm building my first app based on material from http://javatechig.com/video/json-feed-reader-in-android.
Everything goes ok so far, but I found one bug with ListView elements, which I can not manage to resolve by myself :(
I have extended list_row_layout.xml by 2 fields:
<Button
android:layout_width="wrap_content"
android:layout_height="20dp"
android:text="komcie"
android:textSize="11sp"
android:id="#+id/loadComments"
android:layout_gravity="center|bottom"
android:background="#bbb"
android:layout_marginLeft="5dp"
android:enabled="true"
android:clickable="true"
android:onClick="clickedLoadComments"
android:elegantTextHeight="true"
android:layout_toRightOf="#id/thumbImage"
android:layout_below="#+id/content"
android:padding="1px" />
<ListView
android:id="#+id/comment_list"
android:layout_toRightOf="#id/thumbImage"
android:layout_below="#+id/content"
android:paddingTop="5dp"
android:layout_marginTop="0dp"
android:paddingLeft="5dp"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:cacheColorHint="#00000000"
android:dividerHeight="1dp"
android:focusable="false"
android:listSelector="#drawable/list_selector_flatcolor"
android:visibility="invisible" />
Button.android:onClick="clickedLoadComments" function load Json with elements into ListView/comment_list. It works quite fine. But if there are more elements than could be displayed on screen (~8 elements) there is a bug. Comments from clicked element are loaded into every 8th element in a ListView.
Some code:
public void clickedLoadComments(View v)
{
try {
View parent = (View)v.getParent();
ViewHolder t = (ViewHolder) parent.getTag();
if( parent != null ) {
this.loadCommentsForLeaf(parent);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
protected void loadCommentsForLeaf( View view )
{
String tmpUrl = "http://some.url.com/Ajax/LoadComments?lid=" + this.currentLeafInUse;
JSONObject commentsJson = this.getJSONFromUrl(tmpUrl);
this.parseJsonComments(commentsJson);
if( commentsJson != null )
this.updateCommentList(view);
}
public void updateCommentList( View view) {
commentListView = (ListView) view.findViewById(R.id.comment_list);
commentListView.setVisibility(View.VISIBLE);
CommentListAdapter cla = new CommentListAdapter(this, this.commentList.get(this.currentLeafInUse));
commentListView.setAdapter(cla);
// Set list height.
ViewGroup.LayoutParams params = commentListView.getLayoutParams();
params.height = setListViewHeightBasedOnItems(commentListView) + 20;
commentListView.setLayoutParams(params);
commentListView.requestLayout();
}
CustomListAdapter.java code is mostly the same as the one in tutorial.
I would really appreciate help as I have spent many hours figuring it out with not success :(
This is just a guess. You might post your Adapter code and your parseJsonComments also if this does not work.
The Cause:
The problem you are describing might be caused due to the recycling and the reusage of Views. Take a look at this image from http://android.amberfog.com
As you can see the 1. items is reused and becomes the 8. item after scrolling.
Let's assume that Item 1 has an OnClickListener which updates a Text of the item.
For example we set the text to "clicked" after the OnClickListener is triggered.
Because item 1 is reused to create item 8, item 8 will also display the text "clicked".
The Solution:
The usual way is to save all states/content in a List(or whatever) and update everything in the getView call. So if you want to update text:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
...
holder.textView.setText(jsonTexts[position]);
...
return convertView;
}
And if you want to update an item just update the List in your Adapter which holds the content/JsonObjects(etc.) and call notifyDataSetChanged.
public void updateCommentList(JSONObject commentsJson, int position) {
// does not exist you might create something
//like that in your Adapter class
commentListAdapter.updateItem(commentsJson,position);
commentListAdapter.notifyDataSetChanged();
}
After i populate the listview i call this method:
private void registerClickCallback() {
ListView list = (ListView) findViewById(R.id.lv);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked,
int position, long id) {
String xx = position+ ":" + id;
//then you can do what ever you want
}
});
}
I have a listview in my app, which is declared in XML, then the content is passed to it in code based on a string array which I have declared in XML. I'm new to android programming, but I was wondering how I could make the text in certain listview elements bold and darken the listview background behind it.
I have my set names as an array in my strings.xml:
<string-array name="setsArray">
<item>set1</item>
<item>set2</item>
<item>set3</item>
<item>set4</item>
<item>set5</item>
<item>set6</item>
</string-array>
I have my listview declared in the activity's layout.xml
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_below="#+id/app_bar"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
And in the code of the activity I have this:
final ListView setList = (ListView) findViewById(R.id.listView);
setList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, getResources().getStringArray(R.array.setsArray)));
setList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int itemPosition = position;
String itemValue = (String) setList.getItemAtPosition(itemPosition);
if (!itemValue.equals("SPANISH")){
Intent intent = new Intent(view.getContext(), SetViewActivity.class);
intent.putExtra("value", itemValue);
startActivity(intent);
}
}
});
Note that this code takes the name of the set that was clicked on, and passes it onto the next activity with the intent so it knows what to display. If possible I need to keep this intact or replace it with another system which sends something which I can use to distinguish the sets in the next activity.
because you don't use a custom adapter (I guess), try this please:
<string-array name="setsArray">
<item>set1</item>
<item>set2</item>
<item>set3</item>
<item>set4</item>
<item> <![CDATA[ <b>set5</b> ]]> </item>
<item>set6</item>
</string-array>
I hope android using Html.fromHtml() by default :)
Android:Make characters bold in xml
Please watch The World of ListView. It explains the important aspects of ListViews and how to make an adapters for your ListView. Pay particular attention to the part about using getItemViewType() and getViewTypeCount().
I think you'll have to implement custom ListAdapter. In getView() method you'll be able to change style of item based on index.
As a side note, I don't see a reason why you wouldn't use RecyclerView. It's a more flexible and up to date choice for creating lists.
With RecyclerView it could be done like this:
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.mTextView.setText(mDataset[position]);
if(position == 5) holder.mTextView.setTypeface(null, Typeface.BOLD);
}
i am having a list view in which i would like to give a background color to a row when it is pressed.When i select an item its changing the color but the problem is when i scroll down other rows too are got colored.I don't want that.
Here is my code:
Thanks in advance
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
final String item = (String) parent.getItemAtPosition(position);
Toast.makeText(getBaseContext(), item, Toast.LENGTH_LONG).show();
view=parent.getChildAt(position);
view.setBackgroundColor(Color.GREEN);
}
});
}
I think you should handle that in your adapter. A listview re-uses listelements and in your case the one with green background will be reused when you scroll. Instead you should tell your adapter which item was clicked
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
((YourAdpater)listView.getAdapter()).setSelected(position);
}
});
And in your Adapter's getView() you can then set a background if the current position equals the selected one or not...
Or look at the listview's choice mode http://developer.android.com/reference/android/widget/AbsListView.html#attr_android:choiceMode
I'm not really familiar with it, but it might be helpful...
The nicest way to handle this is to set listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);, which allows you to select multiple list items.
To highlight the selected items, all you have to do is create a custom background selector, which defines how the items will look like in which state. For your example this would be something like this:
selector.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:color/white" android:state_activated="false"/>
<item android:drawable="#android:color/green" android:state_activated="true"/>
</selector>
Put this file in your drawable folder and give your list items this background like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/selector">
...
</LinearLayout>
This way you don't have to handle clicks on the items.
You can retrieve the selected items via listview.getCheckedItemPositions()
To highlight a ListView you dont have to manually colour them, Android already has a function for it.
m_ResultsArrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_activated_1,m_ResultsArray)
Instead of using a simple_list_item_1 use a simple_list_item_activated_1. This will allow ur list to be highlighted and you can even check which one is checked by using
this.m_ResultsListView.getCheckedItemPosition();
Hopefully this answers your question :>
I am working on a project in which I need to dynamically add TextView and Spinner as well. I was able to add these two things dynamically from my program successfully.
Now when I was trying to select some items in the Spinner, that items is not getting shown in my emulator but the items that I selected gets shown in the Toast.
Does I need to do anything to make that item selected in Spinner?
for (Map.Entry<String, String> entry : mapColumns.entrySet()) {
spinnerArray = new ArrayList<String>();
final TextView rowTextView = new TextView(cont);
final Spinner spinner = new Spinner(cont);
rowTextView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
spinner.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
for(String s: entry.getValue().split(",")) {
System.out.println(s);
s = s.replaceAll("[^a-zA-Z0-9]+","");
spinnerArray.add(s);
}
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(cont, android.R.layout.simple_spinner_dropdown_item, spinnerArray);
rowTextView.setText(entry.getKey());
rowTextView.setTypeface(null, Typeface.BOLD);
spinner.setAdapter(spinnerArrayAdapter);
// add the listener
spinner.setOnItemSelectedListener(new CustomOnItemSelectedListener());
layout.addView(rowTextView);
layout.addView(spinner);
}
class CustomOnItemSelectedListener implements OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view, int pos,
long id) {
Toast.makeText(
parent.getContext(),
"OnItemSelectedListener : "
+ parent.getItemAtPosition(pos).toString(),
Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
Below is my XML Layout-
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/button1"
android:layout_width="100px"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal|center"
android:gravity="center_vertical|center_horizontal"
android:text="Save" />
</LinearLayout>
</ScrollView>
Here mapColumns will hev Key-Value pair. So in the Spinner all the items are getting shown from the Value of that map.
Problem Statement:-
Now I need to make sure if anybody is selecting any items in the Spinner, it should get selected and be visible to other person.
Below is the image in which I have selected items in the Spinner but it is not getting shown and also TextView is also very light in color-
The below code which you are using to populate the spinnerArray looks suspicious because it will remove all the characters from the string.
for(String s: entry.getValue().split(",")) {
///System.out.println(s); move this print statement to below line and see what it prints in your logs
s = s.replaceAll("[^a-zA-Z0-9]+","");
System.out.println(s);
spinnerArray.add(s);
}
So if the spinnerArray is provided with empty string it will come up with empty spinner. I would suggest comment out the whole block and then try your app and see if the problem persist.
If you want the spinner to comeup with a selected item then add the following line:
spinner.setSelection (0);