I'm completely new to Java/Android and am stuck with listviews.
What I want is to have 4 lines in a row in listview with different font styles
rowlayout.xml
<TextView
android:id="#+id/1"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/2"
android:textSize="30sp"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/3"
android:typeface="sans"
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/4"
android:typeface="sans"
android:textSize="15sp"
android:textStyle="italic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
I have this in a separate xml file
results.xml
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#id/TitleLbl" >
</Listview>
and my array adapter looks like this
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.rowlayout, R.id.2, Array);
setListAdapter(adapter);
What I'm trying to do is get an arraylist (containing ID, name, surname and number) to populate the listview so that each information is on its own line in the row.
the array adapter above works, but each of the four informations is in their own row.
Can anyone help?
(also, I've scoured the internet to try and sort this out, but can't seem to find anything that helps me)
You may need to use custom list view with custom array adapter. Refer this link for example.
Content:
The Android HelloListView ( http://developer.android.com/resources/tutorials/views/hello-listview.html ) tutorial shows how to bind a ListView to an array of string objects, but you'll probably outgrow that pretty quickly. This post will show you how to bind the ListView to an ArrayList of custom objects, as well as create a multi-line ListView.
Let's say you have some sort of search functionality that returns a list of people, along with addresses and phone numbers. We're going to display that data in three formatted lines for each result, and make it clickable.
First, create your new Android project, and create two layout files. Main.xml will probably already be created by default, so paste this in:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_height="wrap_content"
android:text="Custom ListView Contents"
android:gravity="center_vertical|center_horizontal"
android:layout_width="fill_parent" />
<ListView
android:id="#+id/ListView01"
android:layout_height="wrap_content"
android:layout_width="fill_parent"/>
</LinearLayout>
Next, create a layout file called custom_row_view.xml. This layout will be the template for each individual row in the ListView. You can use pretty much any type of layout - Relative, Table, etc., but for this we'll just use Linear:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/name"
android:textSize="14sp"
android:textStyle="bold"
android:textColor="#FFFF00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/cityState"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Now, add an object called SearchResults. Paste this code in:
public class SearchResults {
private String name = "";
private String cityState = "";
private String phone = "";
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setCityState(String cityState) {
this.cityState = cityState;
}
public String getCityState() {
return cityState;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPhone() {
return phone;
}
}
This is the class that we'll be filling with our data, and loading into an ArrayList.
Next, you'll need a custom adapter. This one just extends the BaseAdapter, but you could extend the ArrayAdapter if you prefer.
public class MyCustomBaseAdapter extends BaseAdapter {
private static ArrayList<SearchResults> searchArrayList;
private LayoutInflater mInflater;
public MyCustomBaseAdapter(Context context, ArrayList<SearchResults> results) {
searchArrayList = results;
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return searchArrayList.size();
}
public Object getItem(int position) {
return searchArrayList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.custom_row_view, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView.findViewById(R.id.name);
holder.txtCityState = (TextView) convertView.findViewById(R.id.cityState);
holder.txtPhone = (TextView) convertView.findViewById(R.id.phone);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtName.setText(searchArrayList.get(position).getName());
holder.txtCityState.setText(searchArrayList.get(position).getCityState());
holder.txtPhone.setText(searchArrayList.get(position).getPhone());
return convertView;
}
static class ViewHolder {
TextView txtName;
TextView txtCityState;
TextView txtPhone;
}
}
(This is basically the same as the List14.java API demo)
Finally, we'll wire it all up in the main class file:
public class CustomListView extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList<SearchResults> searchResults = GetSearchResults();
final ListView lv1 = (ListView) findViewById(R.id.ListView01);
lv1.setAdapter(new MyCustomBaseAdapter(this, searchResults));
lv1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Object o = lv1.getItemAtPosition(position);
SearchResults fullObject = (SearchResults)o;
Toast.makeText(ListViewBlogPost.this, "You have chosen: " + " " + fullObject.getName(), Toast.LENGTH_LONG).show();
}
});
}
private ArrayList<SearchResults> GetSearchResults(){
ArrayList<SearchResults> results = new ArrayList<SearchResults>();
SearchResults sr1 = new SearchResults();
sr1.setName("John Smith");
sr1.setCityState("Dallas, TX");
sr1.setPhone("214-555-1234");
results.add(sr1);
sr1 = new SearchResults();
sr1.setName("Jane Doe");
sr1.setCityState("Atlanta, GA");
sr1.setPhone("469-555-2587");
results.add(sr1);
sr1 = new SearchResults();
sr1.setName("Steve Young");
sr1.setCityState("Miami, FL");
sr1.setPhone("305-555-7895");
results.add(sr1);
sr1 = new SearchResults();
sr1.setName("Fred Jones");
sr1.setCityState("Las Vegas, NV");
sr1.setPhone("612-555-8214");
results.add(sr1);
return results;
}
}
Notice that we first get an ArrayList of SearchResults objects (normally this would be from an external data source...), pass it to the custom adapter, then set up a click listener. The listener gets the item that was clicked, converts it back to a SearchResults object, and does whatever it needs to do.
Related
Please bear with me as I am new to android studio. I want to make a ScrollView containing images with corresponding name (TextView). I want to be able to select an image by touching it in the ScrollView, but I don't know how. I have implemented the ScrollView like this, I also want to be able to add pictures with a name attached to them.
Main_activity.xml
<HorizontalScrollView
android:id="#+id/scrollFilterView"
android:layout_width="fill_parent"
android:layout_height="130dp"
android:scrollbars="none"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.57"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0">
<LinearLayout
android:id="#+id/gallery"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal" />
</HorizontalScrollView>
scrollview.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/filterView"
android:layout_width="90dp"
android:layout_height="90dp"
app:srcCompat="#android:drawable/sym_def_app_icon"
android:contentDescription="filterView" />
<TextView
android:id="#+id/textFilter"
android:layout_width="90dp"
android:gravity="center"
android:layout_height="wrap_content"
android:text="textFilter" />
MainActivity.java
LayoutInflater inflater = LayoutInflater.from(this);
for (int i = 0; i < NUMBER_OF_FILTERS_GRID; i++ ) {
View scrollView = inflater.inflate(R.layout.scrollview, gallery, false);
TextView textview = scrollView.findViewById(R.id.textFilter);
textview.setText("Filter "+ i);
ImageView filterView = scrollView.findViewById(R.id.filterView);
filterView.setImageResource(R.mipmap.ic_launcher);
gallery.addView(scrollView);
}
}
Some input to if this is the right path to take and what functions i should use is very appreciated :)
Use a RecyclerView instead of a ListView, and used with and adapter, this will grant you more control over each item displayed on the list (in this case in the RecyclerView),
you will need to create and Adapter class, a simple class for your Items and a new XML layout that will serve as the model of each item in the list.
Simple class for your items:
public class dataSetItem {
private Integer image;
private String listItemText;
public Integer getImage() {
return image;
}
public void setImage(Integer image) {
this.image = image;
}
public String getListItemText() {
return listItemText;
}
public void setListItemText(String listItemText) {
this.listItemText = listItemText;
}
}
In your mainActivity remove the listView and for loop, use this instead:
public class MyActivity extends Activity {
private RecyclerView recyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager layoutManager;
private ArrayList mAdapter = new ArrayList();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
recyclerView = (RecyclerView) findViewById(R.id.your_recycler_view);
mDataset.add(dataSetItem("item 1", R.mipmap.ic_launcher))
mDataset.add(dataSetItem("item 2", R.mipmap.ic_launcher))
// You can add more items to the mDataset list and call the adapter again to update the RecyclerView
// use a linear layout manager
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
// specify an adapter (see also next example)
mAdapter = new MyAdapter(myDataset);
recyclerView.setAdapter(mAdapter);
}
// ...
}
Create this XML layout which will serve as the model for each item, called my_item_list_layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center">
<ImageView
android:id="#+id/the_image_i_want_to_click"
android:layout_width="80dp"
android:layout_margin="10dp"
android:layout_height="80dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:background="#color/ADRBlack"
/>
<TextView
android:id="#+id/item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="220dp"
android:textColor="#color/Black"
android:textSize="16sp"
tools:text="Example Restaurant" />
</LinearLayout>
</LinearLayout>
Now the adapter class, in this case called MyAdapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private customItem[] mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class MyViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView textView;
public MyViewHolder(TextView v) {
super(v);
textView = v;
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(customItem[] myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
TextView v = (TextView) LayoutInflater.from(parent.getContext())
.inflate(R.my_item_list_layout, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.textView.setText(mDataset[position].getListItemText);
holder.textView.setBackground(mDataset[position].getImage);
//Now to do something when you clic the image use this
holder.textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
//Your action here
}
});
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.length;
}
}
The idea is I want to display list of mp3 files from SDCARD in listview, each line is also contain a spinner with three items (share, rename and delete), I used custom arrayadapter for this purpose and I am stuck on how to add the spinner on the custom arrayadapter class
this is the activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:theme="#style/AppTheme"
tools:context=".MainActivity"
>
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="416dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="0dp" />
<Button
android:id="#+id/stopBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:layout_marginBottom="28dp"
android:text="Stop" />
</LinearLayout>
this is where i create the spinner
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingLeft="14dp"
>
<TextView
android:id="#+id/text1"
android:layout_width="0dp"
android:layout_height="33dp"
android:layout_weight="1"
android:gravity="center|start"
/>
<Spinner
android:id="#+id/spinner"
android:layout_width="31dp"
android:layout_height="33dp"
android:layout_gravity="right"
android:background="#drawable/download"
>
</Spinner>
</LinearLayout>
here I create the datatype
public class MyDataType {
// Name of the song
private String mSongName;
// Drawable Menu resource ID
private int mSpinner;
/** Audio resource ID for the word */
//private int mAudioResourceId;
//public MyDataType(String vName, int imageResourceId, int audioResourceId){
public MyDataType(String vName, int spinner){
mSongName = vName;
mSpinner = spinner;
//mAudioResourceId = audioResourceId;
}
public String getSongName() {
return mSongName;
}
public int getSpinner() {
return mSpinner;
}
}
here i create the custom adapter
public class SongAdapter extends ArrayAdapter<MyDataType> {
public SongAdapter(Context context, ArrayList<MyDataType> words) {
super(context, 0, words);
}
Spinner mSpinner;
ArrayAdapter<CharSequence> mAdapter;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
MyDataType currentSong = getItem(position);
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.song_list, parent, false);
}
TextView songTextView = (TextView)
listItemView.findViewById(R.id.text1);
songTextView.setText(currentSong.getSongName());
mSpinner = (Spinner) listItemView.findViewById(R.id.spinner);
return listItemView;
}
}
this is the main activity
public class MainActivity extends AppCompatActivity {
private static final String SD_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Xylophone/";
ArrayList<MyDataType> file_list = new ArrayList<MyDataType>();
private final ArrayList<String> songs = new ArrayList<String>();
private MediaPlayer mp = new MediaPlayer();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MediaPlayer mp = new MediaPlayer();
//updatePlayList();
if (ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
fillList();
} else {
ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.READ_EXTERNAL_STORAGE}, 100);
}
final SongAdapter adapter = new SongAdapter(this, file_list);
ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
try{
mp.reset();
mp.setDataSource(SD_PATH + songs.get(position));
mp.prepare();
mp.start();
}catch (IOException e){
Log.v(getString(R.string.app_name),e.getMessage() );
}
}
});
Button stopPlay = (Button) findViewById(R.id.stopBtn);
stopPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mp.stop();
}
});
}
private void fillList() {
File file = new File(SD_PATH );
File list[] = file.listFiles();
for (int i = 0; i < list.length; i++) {
//file_list.add(list[i].getName(),);
songs.add(list[i].getName());
MyDataType myList = new MyDataType(list[i].getName(), R.id.spinner);
file_list.add(myList);
}
}
}
the string value that cotain menu items
<resources>
<string name="app_name">PlayMp3List</string>
<string-array name="spinner_data">
<item>Rename</item>
<item>Delete</item>
<item>Share</item>
</string-array>
</resources>
OK, it seems that you have almost every thing in place that you need. However, there are a few minor changes you will need to make before this is working. First, in the code where you check the permissions if permission is granted, you call fillList(). But in the Else condition, you request the permission. In the code above, you are not showing how you are handling the result of the request for permission. If the permission is granted after the request, then in that case, you must also call fillList() there as well. And, after calling fillList() there, you will also need to recreate the SongAdapter, and also redo the setAdapter on your list view.
In fillList(), you are initializing your myList item with the song title, and the ID of a spinner. You shouldn't be doing that. What you should be doing is populating the myList item with the 'value' of the spinner... and the default should probably be 0.
In your getView() method in the custom Adapter, you are getting the current item based on the position parameter and putting the song title into the textView. Then, you are getting a reference to the Spinner, but you are not doing anything with it. After getting the reference you should be doing something like mSpinner.value = currentSong.getSpinner();
What you want to do in your MyDataType class is to store the value of the spinner, not any reference to the spinner itself. You also need some sort of click event so that if the user changes the value of the spinner in the row, you can update your ArrayList with the new value. That assumes the user can change that selected spinner item, if not, then when you are creating the list, you have to figure out what value to set each song's spinner value with, which you are not doing.
Your Adapter code should look like this. Note the removal of getContext().
public class SongAdapter extends ArrayAdapter<MyDataType> {
Context mContext = null;
public SongAdapter(Context context, ArrayList<MyDataType> words) {
super(context, 0, words);
mContext = context;
}
Spinner mSpinner;
ArrayAdapter<CharSequence> mAdapter;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
MyDataType currentSong = getItem(position);
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(mContext.inflate(R.layout.song_list, parent, false);
}
TextView songTextView = (TextView)
listItemView.findViewById(R.id.text1);
songTextView.setText(currentSong.getSongName());
mSpinner = (Spinner) listItemView.findViewById(R.id.spinner);
mSpinner.value = currentSong.getSpinner();
return listItemView;
}
}
In your list item click method you will need to set a breakpoint to see that the path you are passing in mp.setDataSource is a valid path. It is possible that your SD_PATH needs a '/' at the end or something.
In your layout.xml file you would define your spinner like this:
<Spinner
android:id="#+id/spinner1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="#array/country_arrays"
android:prompt="#string/country_prompt" />
Where the entries #array/country_arrays points to the list that you defined in Strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">MyAndroidApp</string>
<string name="country_prompt">Choose a country</string>
<string-array name="country_arrays">
<item>Malaysia</item>
<item>United States</item>
<item>Indonesia</item>
<item>France</item>
<item>Italy</item>
<item>Singapore</item>
<item>New Zealand</item>
<item>India</item>
</string-array>
</resources>
You are missing the value in your spinner xml definition:
<Spinner
android:id="#+id/spinner"
android:layout_width="31dp"
android:layout_height="33dp"
android:layout_gravity="right"
android:background="#drawable/download"
android:entries="#array/spinner_data"
>
</Spinner>
I am trying to make a to-do list using an EditText and a ListView. How can I change the text font, color and size? I have seen a couple answers using array adapters, but don't know how to apply them to dynamically created ListView items.
Here is what I have so far:
ActivityMain.xml
<RelativeLayout
android:id="#+id/AgendaRL"
android:orientation="vertical"
android:background="#3E2723"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/agenda"
android:layout_width="370sp"
android:layout_height="wrap_content"
android:text="#string/agenda"
android:textSize="40sp"
android:textColor="#b7950b"
android:layout_marginTop="12sp"
android:layout_marginLeft="12sp"
android:layout_marginStart="12sp"
android:layout_marginBottom="0sp" />
<View
android:background="#b7950b"
android:layout_below="#+id/agenda"
android:layout_width="28sp"
android:layout_height="36sp"/>
<EditText
android:id="#+id/aTask"
android:layout_below="#+id/agenda"
android:background="#drawable/ribbon"
android:inputType="text"
android:text="#string/Add_Task"
android:textColor="#3E2723"
android:maxLength="22"
android:maxLines="1"
android:layout_width="330sp"
android:layout_height="36sp"
android:textSize="28sp"
android:layout_marginLeft="28sp"
android:layout_marginStart="28sp"/>
<Button
android:id="#+id/Done"
style="?android:attr/borderlessButtonStyle"
android:layout_marginLeft="250sp"
android:layout_marginStart="250sp"
android:background="#b7950b"
android:text="#string/Done"
android:textColor="#3E2723"
android:textSize="18sp"
android:layout_below="#+id/agenda"
android:layout_width="48sp"
android:layout_height="36sp"
android:onClick="DoneClick"/>
<ListView
android:id="#+id/LVAgenda"
android:layout_below="#+id/aTask"
android:divider="#android:color/transparent"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
MainActivity.Java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView LVAgenda = (ListView) findViewById(R.id.LVAgenda);
arrayListAgenda = new ArrayList<String>();
arrayAdapterAgenda = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, arrayListAgenda);
LVAgenda.setAdapter(arrayAdapterAgenda);
}
public void DoneClick(View v){
EditText aTask = (EditText)findViewById(R.id.aTask);
String agenda = aTask.getText().toString().trim();
if(agenda.isEmpty()){
return;
}
arrayAdapterAgenda.add(agenda);
aTask.setText("Add task");
}
As commonsware said you can use getView() of ArrayAdapter to do this.
I have implemented Facebook friend selector with ListAdapter. I will share the code. May be it helps. Please try.
First make a XML file in layout that defines the layout of each item of your 'to do list'.
In my case it is a facebook profile image and a checked textbox. (There is also a spacer for alignment)
Facebook.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/img"
android:layout_width="50dp"
android:layout_height="50dp"
android:paddingLeft="10dp"/>
<CheckedTextView
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical|right"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:textColor="#android:color/black"
android:textStyle="bold" />
</LinearLayout>
<View
android:id="#+id/spacer"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#android:color/white"/>
</LinearLayout>
Now prepare your data array. In my case it is custom class array where each element contains a facebook name, profilepic, and a boolean.
public class Item{
public final String text;
public final Drawable icon;
public boolean isChecked;
public Item(String text, Drawable icon, boolean ischeck) {
this.text = text;
this.icon = icon;
this.isChecked = ischeck;
}
#Override
public String toString() {
return text;
}
}
I call the below code by passing friendsArray from another activity.
final Item[] items = new Item[friendsArray.length];
try {
int a = 1;
for (int i = 0; i < friendsArray.length; i++) {
tsk = new DownloadImageTask();
Bitmap bmp = (Bitmap) tsk.execute(new RaceActivity.FriendInfo[]{friendsArray[i]}).get();
Resources res = getActivity().getResources();
drawable = new BitmapDrawable(res, bmp);
items[i] = new Item(friendsArray[i].name, drawable,false);
}
}
catch(Exception ex)
{
}
Now your data array is prepared. You can pass this to ListAdapter(items in my case).
Its nice to understand the working of a List adapter. I created a scrollable List. What this logic does is it reuses the Views while scrolling.
ListAdapter adapter = new ArrayAdapter<Item>(
getActivity(),
android.R.layout.select_dialog_item,
android.R.id.text1,
items){
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
FaceBookHolder fb = new FaceBookHolder();
if(convertView == null)
{
LayoutInflater inflater = (LayoutInflater) getActivity().getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.facebook,null);
fb.Name = (CheckedTextView) v.findViewById(R.id.name);
fb.img = (ImageView) v.findViewById(R.id.img);
fb.spacer = (View) v.findViewById(R.id.spacer);
fb.Name.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
CheckedTextView cv = (CheckedTextView)v;
if(cv.isChecked())
cv.setChecked(false);
else
cv.setChecked(true);
for(int i =0;i< items.length; i++)
{
if(items[i].text == cv.getText())
{
items[i].isChecked = cv.isChecked();
}
}
}
});
v.setTag(fb);
}
else
fb = (FaceBookHolder) v.getTag();
Item itm = items[position];
fb.Name.setText(itm.text);
fb.img.setImageDrawable(itm.icon);
fb.Name.setChecked(itm.isChecked);
return v;
}
};
you get the view in getView(), so you can modify it however you want.(change color , font etc)
Hope it helps! cheers!
I have 4 fields on a custom row layout for a listview. I have 4 fields in my array that I want to map to those 4 fields on the listview:
cat_ID_PK
cat_name
cat_amount
is_recurring
I have no idea how to correctly do that. Here's what I have so far:
private void loadListView(Expenses[] mExpenseArray) {
//This code will write the "name" variable correctly to the logcat, so I know I'm
getting the right values in my array.
String name = mExpenseArray[0].getCatName();
Log.v("log_tag", name);
ArrayAdapter<Expenses> adapter = new ArrayAdapter<Expenses>(getApplicationContext(), R.layout.list_row, R.id.catName, mExpenseArray);
final ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter);
}
This code only populates R.id.catName, but when it populates it, it looks like this: mypackage#8ed455 (or something similar). None of the other fields are populated at all, which I'm guessing has to do with the 3rd parameter in my ArrayAdapter being R.id.catName. However, if I take this parameter out I get this error:
java.lang.IllegalStateException: ArrayAdapter requires the resource ID to be a TextView
Here is the code for my custom row layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/list_selector"
android:orientation="horizontal"
android:padding="5dip" >
<TextView
android:id="#+id/catName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dip"
android:layout_centerVertical="true"
android:paddingBottom ="10dip"
android:text="#string/catName"
android:textColor="#040404"
android:textSize="25dip"
android:textStyle="bold"
android:typeface="sans" />
<TextView
android:id="#+id/catAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="27dip"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:paddingBottom ="10dip"
android:text="$45.00"
android:textColor="#040404"
android:textSize="25dip"
android:textStyle="bold"
android:typeface="sans" />
<TextView
android:id="#+id/catType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/catName"
android:layout_alignLeft="#+id/catName"
android:paddingTop="5dip"
android:layout_centerHorizontal="true"
android:text="#string/catType"
android:textColor="#343434"
android:textSize="15dip" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="catID"
android:id="#+id/catID"
android:layout_alignBottom="#+id/catType"
android:layout_toRightOf="#+id/catType"
android:layout_toEndOf="#+id/catType"
android:layout_marginLeft="27dp"
android:visibility="invisible" />
</RelativeLayout>
How can I correctly map my 4 array fields to my ListView?
make a custom adapter like this and then assign the values to the text views
pass array like this to adapter
UserList disadpt = new UserList(HomePage.this, mEmployeeList);
userList.setAdapter(disadpt);
then in adapter do this ..
public class UserList extends BaseAdapter
{
private Context mContext;
private ArrayList<Employee> items;
public UserList(Context c, ArrayList<Employee> items)
{
this.mContext = c;
this.items = items;
}
public int getCount() {
return this.items.size();
}
public Object getItem(int position) {
return this.items.get(position);
}
public long getItemId(int position) {
return position;
}
#Override
public View getView(int pos, View child, ViewGroup arg2) {
Holder mHolder;
LayoutInflater layoutInflater;
if (child == null) {
layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
child = layoutInflater.inflate(R.layout.listcell, null);
mHolder = new Holder();
//mHolder.txt_id = (TextView) child.findViewById(R.id.txt_id);
mHolder.txt_fName = (TextView) child.findViewById(R.id.txt_fName);
mHolder.txt_lName = (TextView) child.findViewById(R.id.txt_lName);
mHolder.txt_userName = (TextView) child.findViewById(R.id.txt_userName);
child.setTag(mHolder);
} else {
mHolder = (Holder) child.getTag();
}
Employee employee = this.items.get(pos);
ArrayList<String> employeeInfo = new ArrayList<String>();
employeeInfo.add(employee.employeeId);
employeeInfo.add(employee.firstName);
employeeInfo.add(employee.lastName);
mHolder.Details.setTag(employeeInfo);
mHolder.txt_fName.setText(employee.firstName + " " + employee.lastName);
mHolder.txt_userName.setText(employee.emailId);
return child;
}
public class Holder
{
//TextView txt_id;
TextView txt_fName;
TextView txt_lName;
TextView txt_userName;
Button Details;
}
}
hope this helps ...
Create String type of array Adapter and use-
adapter.add(mExpenseArray[0].getCatName());
by using any loop.
I've been looking on here for quite some time and I cannot find an answer to my problem. There are many similar issues. But I haven't been able to come up with any solution that works. I am very new to android/java programming so I really appreciate any help.
Background: I have an activity screen that contains 2 listviews. The first listview contains a list of names coming from a database. (This is working correctly).
Then when a user clicks on one of the names in the list, the onItemClick event fires and builds a cursor from all the data associated from the name. (Have verified that I am getting a cursor with valid results).
Problem: When I try to put the resulting cursor into a SimpleCursorAdapter to set my listadpter to, I am receiving no errors, but I'm not getting anything displayed to the screen.
I have data coming from a SQLite database. It is simply 4 columms with X number of rows. All I want to do is display everything on the list and then maybe do some analysis.
Here is my code:
public class TipCalculator_w_Database extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.databaseinfoscreen);
ListView lv1 = null;
lv1 = (ListView) findViewById (R.id.List1);
final ListView lv2;
lv2 = (ListView) findViewById (R.id.List2);
final DataBase showData = new DataBase(getApplicationContext());
showData.open();
Cursor NameList = showData.GetAllNames();
startManagingCursor(NameList);
// Create an ArrayAdapter, that will actually make the Strings above
// appear in the ListView
int i = NameList.getCount();
String[] FinalString = new String[i];
int j = 0;
while (NameList.moveToNext()) {
FinalString[j] = NameList.getString(0);
j++;
}
if(j != 0)
{
lv1.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_gallery_item, FinalString));
}
NameList.close();
showData.close();
lv1.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String selectedName = ((TextView) view).getText().toString();
Context ctx= parent.getContext();
final DataBase showData = new DataBase(getApplicationContext());
showData.open();
final String[] columns = new String[] { showData.KEY_ROWID, showData.KEY_NAME, showData.KEY_BILL, showData.KEY_TIP};
final int[] to = new int[] { R.id.ID_list, R.id.Name_list, R.id.Bill_list, R.id.Tip_list};
Cursor NewEntry = showData.GetRowByName(selectedName);
startManagingCursor(NewEntry);
lv2.setAdapter(new SimpleCursorAdapter(ctx, R.layout.listlayout, NewEntry, columns, to));
showData.close();
NewEntry.close();
// Back Button Functionality
Button backButton = (Button) findViewById(R.id.Back);
backButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent myIntent = new Intent(v.getContext(), Tipscreen.class);
startActivityForResult(myIntent, 0);
}
}
);
}
}
Here is my XML Files
listlayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/ID_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10px" />
<TextView
android:id="#+id/Name_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10px" />
<TextView
android:id="#+id/Bill_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10px" />
<TextView
android:id="#+id/Tip_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10px"/> </LinearLayout>
-- databaseinfoscreen.xml --
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<ListView android:text="List" android:id="#+id/List1" android:layout_width="wrap_content" android:textSize="18px" android:layout_height="fill_parent">
</ListView>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<ListView android:text="List" android:id="#+id/List2" android:layout_width="wrap_content" android:textSize="18px" android:layout_height="fill_parent">
</ListView>
</LinearLayout>
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<Button android:text="#string/back" android:layout_alignParentBottom="true" android:id="#+id/Back" android:layout_width="wrap_content" android:textSize="18px" android:layout_height="40px"></Button>
</RelativeLayout>
</LinearLayout>
Hopefully this is enough to go off of, if there is any more information needed please let me know. I am getting all the information I need in the cursor it just isn't being displayed. I am open to alternate means of doing this. However, I cannot make this particular class extend ListActivity since it needs to be extending activity.
Also of note. I have been able to display to that listview using the following line of code. Unfortunately this is only displays one column rather than all columns which I want.
lv2.setAdapter(new ArrayAdapter<String>(ctx, android.R.layout.simple_gallery_item, FinalString));
Where FinalString is simply a full column of data from the database that was manipulated into an array.
Thanks for the help.
Well since no one responded, I figured I'd answer this myself.
Here are the steps, I've got this working for a different project so I'll summarize. I can go into more detail if anyone needs it.
XML:
<ListView android:text="List" android:id="#+id/android:list" android:layout_width="wrap_content" android:scrollbars="horizontal" android:textSize="18px" android:layout_height="fill_parent" android:minHeight="120px">
</ListView>
Step 1: Create a Cursor and populate using DB functions (not shown)
String dbCount = showData.getTotalCount();
Cursor GetAllData = showData.GetAllData();
startManagingCursor(GetAllData);
Step 2: Create an ArrayList that comprises a bunch of get values and fill the list with items from the cursor.
int i = GetAllData.getCount();
ArrayList<DB_Get_Values> dbList = new ArrayList<DB_Get_Values>();
while (GetAllData.moveToNext()) {
DB_Get_Values w = new DB_Get_Values(GetAllData.getString(0), GetAllData.getString(1), GetAllData.getString(2));
dbList.add( w );
j++;
}
Step 3: Create an adapter class that will be used to control the display of the listview
DBAdapter T_Adapter = new DBAdapter(
this,
dbList );
setListAdapter( T_Adapter );
GetAllData.close();
DB_Get_Values Class: Full of Getters
public class DB_Get_Values {
public String P_Key = "";
public String Mac_addr = "";
public String SDK_VRS = "";
public DB_Get_Values( String P_Key, String Mac_addr, String SDK_VRS)
{
this.P_Key = P_Key;
this.Mac_addr = Mac_addr;
this.SDK_VRS = SDK_VRS;
}
public String get_Mac_addr() {
return Mac_addr;
}
public String get_P_Key() {
return P_Key;
}
public String get_SDK_VRS() {
return SDK_VRS;
}
}
Class DBAdapter: Get's the values to put into the listview and allows for programatically controlling the display.
class AdapterView extends LinearLayout {
public AdapterView(Context context,
DB_Get_Values list ) {
super( context );
this.setOrientation(HORIZONTAL);
LinearLayout.LayoutParams PkeyParams =
new LinearLayout.LayoutParams(40, LayoutParams.WRAP_CONTENT);
PkeyParams.setMargins(1, 1, 1, 1);
TextView Pkey = new TextView( context );
Pkey.setText( list.get_P_Key() );
Pkey.setTextSize(14f);
Pkey.setTextColor(Color.WHITE);
addView( Pkey, PkeyParams);
LinearLayout.LayoutParams MacAddrParams =
new LinearLayout.LayoutParams(100, LayoutParams.WRAP_CONTENT);
MacAddrParams.setMargins(1, 1, 1, 1);
TextView MacAddr = new TextView( context );
MacAddr.setText( list.get_Mac_addr() );
MacAddr.setTextSize(14f);
MacAddr.setTextColor(Color.WHITE);
addView( MacAddr, MacAddrParams);
LinearLayout.LayoutParams SDK_VRSParams =
new LinearLayout.LayoutParams(20, LayoutParams.WRAP_CONTENT);
SDK_VRSParams.setMargins(1, 1, 1, 1);
TextView SDK_VRS = new TextView( context );
SDK_VRS.setText( list.get_SDK_VRS() );
SDK_VRS.setTextSize(14f);
SDK_VRS.setTextColor(Color.WHITE);
addView( SDK_VRS, SDK_VRSParams);
}
}
public class DBAdapter extends BaseAdapter {
private Context context;
private List<DB_Get_Values> list;
public DBAdapter(Context context, List<DB_Get_Values> list ) {
this.context = context;
this.list = list;
}
public int getCount() {
return list.size();
}
public Object getItem(int position) {
return list.get(position);
}
public long getItemId(int position) {
return position;
}
}
Step 5: You are now done! Change the parameters in AdapterView class to modify how it looks. Hopefully this helps someone.