i'm new to android. I'm just trying to make one simple search functionality for my app. My app consists one ListView and one SearchView for search. My ListView contents are listed from a String list using custom adapter which is extends BaseAdapter
Now, what i'm trying to do is, i want to search any records from ListView For example, if i've some records like
aa abb ...
So, when i type some record name like a
The listview should listed the records which is started from a... I've referred something for this, from i got addTextChangedListener But, i don't know how to do this?
And, Can we do this same functionality with click of button
Has anyone having any idea on this? Thanks in advance
MainActivity.java
public class MainActivity extends ActionBarActivity {
ListView list ;
private SearchView mSearchView;
String [] a = {"aa","abb","cc","dd","ee","ff","gg","hh","ii","jj","kk","ll"};
String [] b = {"1","2","3","4","5","6","7","8","9","10","11","12"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSearchView = (SearchView) findViewById(R.id.search_view);
mSearchView.setOnQueryTextListener(new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)) {
list.clearTextFilter();
} else {
Log.i("WSM",newText);
list.setFilterText(newText.toString());
}
return true;
}
});
list = (ListView) findViewById(R.id.lista);
list.setTextFilterEnabled(true);
list.setAdapter(new MyAdapter(this, a, b));
setupSearchView();
}
private void setupSearchView() {
mSearchView.setIconifiedByDefault(false);
mSearchView.setSubmitButtonEnabled(true);
mSearchView.setQueryHint("Search Here");
}
class SingleRow{
String ssid;
String pass;
public SingleRow (String ssid, String pass){
this.ssid = ssid;
this.pass = pass;
}
}
class MyAdapter extends BaseAdapter {
ArrayList<SingleRow> myList ;
Context c;
public MyAdapter (Context c, String[] ssid, String [] pass){
this.c = c;
myList = new ArrayList<SingleRow>();
for (int i = 0; i<ssid.length; i++){
myList.add(new SingleRow(ssid[i],pass[i]));
}
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return myList.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return myList.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) c.getSystemService(LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.singlerow, parent ,false);
TextView TV_ssid = (TextView) row.findViewById(R.id.ssid);
TextView TV_pass = (TextView) row.findViewById(R.id.pass);
SingleRow tmp = myList.get(position);
TV_ssid.setText(tmp.ssid);
TV_pass.setText(tmp.pass);
return row;
}
}
}
singlerow.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="183dp"
android:layout_height="wrap_content"
android:layout_weight="0.82"
android:orientation="vertical" >
<TextView
android:paddingTop="10sp"
android:id="#+id/ssid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SSID: "
android:textAppearance="?android:attr/textAppearanceMedium"
android:typeface="monospace" />
<TextView
android:id="#+id/pass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PASS:"
android:textAppearance="?android:attr/textAppearanceMedium"
android:paddingBottom="10sp"
android:typeface="monospace"/>
</LinearLayout>
<ImageButton
android:id="#+id/imageButton1"
android:layout_width="56dp"
android:layout_height="49dp"
android:layout_gravity="center"
android:src="#drawable/abc_ic_menu_moreoverflow_normal_holo_light" />
</LinearLayout>
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<SearchView
android:id="#+id/search_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/lista"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
For searching feature I recommend you this component:
https://github.com/matessoftwaresolutions/AndroidFilterableList
This allows you to filter whatever you want in an extremely easy way. Change filters dynamically etc.
You would have to modify your code in order to adapt it to this way of working... but I think it worths.
Take a look to the sample!!
I hope this would help you.
Related
I am writing the basic task management application. I am using base adapter to work with ListView. I wonder how I can remove (a few) checked values from the list? And how I can remove only one value with long click?
if this posible with my adapter? I tried a few options but nothing worked.
Here is my code.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:id="#+id/btn1"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:text="\u2713"
android:background="#drawable/add_btn"
android:onClick="knopka2"/>
<EditText
android:id="#+id/input"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#id/btn1"
android:hint="put your task here"/>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:divider="#drawable/deriver"
android:layout_below="#+id/input"
android:layout_centerHorizontal="true"
android:choiceMode="multipleChoice" />
<TextView
android:id="#+id/ttl"
android:layout_below="#id/listView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="#+id/tryClear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/ttl"
android:onClick="tryClear"
/>
</RelativeLayout>
This is my Activity:
public class Trird extends AppCompatActivity {
Button btn;
EditText input4;
TextView ttl;
ListView list;
public static ArrayList<String> taskList = new ArrayList<String>();
SparseBooleanArray sparseBooleanArray;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.third);
input4 = (EditText) findViewById(R.id.input);
btn = (Button) findViewById(R.id.btn1);
list = (ListView) findViewById(R.id.listView);
ttl = (TextView)findViewById(R.id.ttl);
}
public String[] putToArray() {
String ag = input4.getText().toString().trim();
if (ag.length() != 0) {
taskList.add(ag);
input4.setText("");
}
String[] abc = taskList.toArray(new String[taskList.size()]);
return abc;
}
public void knopka2(View v) {
final String[] ListViewItems = putToArray(); //
list = (ListView) findViewById(R.id.listView);
list.setAdapter(new MyAdapter(ListViewItems, this));
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View tv, int i, long id) {
///tv.setBackgroundColor(Color.YELLOW);
///ttl.setText("selected: " + list.getAdapter().getItem(i));
sparseBooleanArray = list.getCheckedItemPositions();
String ValueHolder = "";
int a = 0;
while (a < sparseBooleanArray.size()) {
if (sparseBooleanArray.valueAt(a)) {
ValueHolder += ListViewItems[sparseBooleanArray.keyAt(a)] + ",";
}
a++;
}
ValueHolder = ValueHolder.replaceAll("(,)*$", "");
Toast.makeText(Trird.this, "ListView Selected Values = " + ValueHolder, Toast.LENGTH_LONG).show();
if(ValueHolder!=null){
taskList.remove(ValueHolder);
}
}
});
}
}
This is my adapter:
public class MyAdapter extends BaseAdapter {
private final Context context;//Context for view creation
private final String[] data;//raw data
public MyAdapter(String[] data, Context context){
this.data=data;
this.context=context;
}
//how many views to create
public int getCount() {
return data.length;
}
//item by index (position)
public Object getItem(int i) {
return data[i];
}
//ID => index of given item
public long getItemId(int i) {
return i;
}
//called .getCount() times - for each View of item in data
public View getView(int i, View recycleView, ViewGroup parent) {
if(recycleView==null)recycleView = LayoutInflater.from(context).inflate(R.layout.item,null);
((TextView)recycleView).setText(data[i]);//show relevant text in reused view
return recycleView;
}
}
And this is how looks like item in ListView.
<CheckedTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:drawableRight="?android:attr/listChoiceIndicatorMultiple"
/>
The problem is that you are trying removing item using the ListView remove methode.
Just remove the selected item from the list using the remove() method of your Adapter.
A possible way to do that would be:
CheckedTextView checkedText= baseAdapter.getItem([POSITION OF THE SELECTED ITEM]);
baseAdapter.remove(checkedText);
baseAdapter.notifyDataSetChanged();
put this code inside the wanted button click and there you go.
I am new to android programming and this task is really need for my school project. Please kindly help me.
I've string array List - (retrieved from csv)
list = new ArrayList<>(Arrays.asList("111,222,333,444,555,666".split(",")));
myList.setAdapter(new ArrayAdapter<String>(getActivity(),R.layout.cell,list));
The result is showing only line by line text of arrayList. I want to add button to each generated line by line to delete clicked row.
Please how can I do this. Thank you for understanding my problem.
You have to create a custom layout xml which having a single item then you will add your button to this layout along with any other items.
CustomLayout.Xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tvContact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textStyle="bold" />
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Call" />
</RelativeLayout>
Now after creating custom item layout you need listview which holds all items.
MainActivity.xml
.
.
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
.
.
Now in java file just set adapter with our custom layout xml
.
.
list = new ArrayList<String>(Arrays.asList("111,222,333,444,555,666".split(",")));
listview.setAdapter(new MyCustomAdapter(list, context) );
.
.
Custom adapter Class
public class MyCustomAdapter extends BaseAdapter implements ListAdapter {
private ArrayList<String> list = new ArrayList<String>();
private Context context;
public MyCustomAdapter(ArrayList<String> list, Context context) {
this.list = list;
this.context = context;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int pos) {
return list.get(pos);
}
#Override
public long getItemId(int pos) {
return list.get(pos).getId();
//just return 0 if your list items do not have an Id variable.
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.CustomLayout, null);
}
//Handle TextView and display string from your list
TextView tvContact= (TextView)view.findViewById(R.id.tvContact);
tvContact.setText(list.get(position));
//Handle buttons and add onClickListeners
Button callbtn= (Button)view.findViewById(R.id.btn);
callbtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
//do something
}
});
addBtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
//do something
notifyDataSetChanged();
.
}
});
return view;
}
}
We have need ListviewActivity for listing your data
SchoolAdapter which is custom adapter to inflate each individual row
activity_listview which is layout for ListviewActivity
view_listview_row which is required for each individual row
Now create all file as below
For ListviewActivity,
public class ListviewActivity extends AppCompatActivity {
private ListView mListview;
private ArrayList<String> mArrData;
private SchoolAdapter mAdapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listview);
mListview = (ListView) findViewById(R.id.listSchool);
// Set some data to array list
mArrData = new ArrayList<String>(Arrays.asList("111,222,333,444,555,666".split(",")));
// Initialize adapter and set adapter to list view
mAdapter = new SchoolAdapter(ListviewActivity.this, mArrData);
mListview.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
}
For SchoolAdapter,
public class SchoolAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<String> mArrSchoolData;
public SchoolAdapter(Context context, ArrayList arrSchoolData) {
super();
mContext = context;
mArrSchoolData = arrSchoolData;
}
public int getCount() {
// return the number of records
return mArrSchoolData.size();
}
// getView method is called for each item of ListView
public View getView(int position, View view, ViewGroup parent) {
// inflate the layout for each item of listView
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.view_listview_row, parent, false);
// get the reference of textView and button
TextView txtSchoolTitle = (TextView) view.findViewById(R.id.txtSchoolTitle);
Button btnAction = (Button) view.findViewById(R.id.btnAction);
// Set the title and button name
txtSchoolTitle.setText(mArrSchoolData.get(position));
btnAction.setText("Action " + position);
// Click listener of button
btnAction.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Logic goes here
}
});
return view;
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}}
For activity_listview,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#D1FFFF"
android:orientation="vertical">
<ListView
android:id="#+id/listSchool"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#0000CC"
android:dividerHeight="0.1dp"></ListView>
For view_listview_row,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="7.5dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="7.5dp">
<TextView
android:id="#+id/txtSchoolTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="2dp"
android:text="TextView"
android:textColor="#android:color/black"
android:textSize="20dp" />
<Button
android:id="#+id/btnAction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="Click Me" />
At last but not least, do not forgot to add your activity in manifest.xml
Create a custom list view in another file with the only content of each item in the list.
Then create a Custom Adapter extending BaseAdapter and bind it.
Please refer to this website for example.
https://looksok.wordpress.com/tag/listview-item-with-button/
OR
http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/
I'm trying to make a custom listview with multiple values, which have buttons for sorting. This way the listview can be sorted for different values, like year, name and price etc.
I'm still pretty new to Android Studio and coding in general, so if anything is just plain off, then i apologize!
Problem is, nothing is sorted when i press any of the buttons. I tried using a comparable, for sorting in ascending order numerically, but that doesn't seem to work (not getting any errors, just nothing happens).
Here is what i've tried, showing my custom rows first, and then custom list adapter:
My Custom Row Layout:
<TextView
android:layout_width="40dp"
android:layout_height="35dp"
android:layout_marginLeft="10dp"
android:text="Time:"
android:id="#+id/time_label_row"
android:gravity="center"
android:layout_weight="1"/>
<TextView
android:layout_width="40dp"
android:layout_height="35dp"
android:text="time"
android:id="#+id/time_row"
android:gravity="center"
android:layout_weight="1"/>
<TextView
android:layout_width="40dp"
android:layout_height="35dp"
android:layout_marginLeft="10dp"
android:text="Price:"
android:id="#+id/price_label_row"
android:gravity="center"
android:layout_weight="1"/>
<TextView
android:layout_width="40dp"
android:layout_height="35dp"
android:text="price"
android:id="#+id/price_row"
android:gravity="center"
android:layout_weight="1"/>
<TextView
android:layout_width="40dp"
android:layout_height="35dp"
android:layout_marginLeft="10dp"
android:text="Year:"
android:id="#+id/year_label_row"
android:gravity="center"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="35dp"
android:text="year"
android:id="#+id/year_row"
android:gravity="center"
android:layout_weight="1"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/colorPrimaryDark"
/>
My Custom Listview (only the buttons insteresting here):
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp">
<Button
android:text="Time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/sort_time"
android:layout_weight="1"
android:onClick="TimeSortClick"/>
<Button
android:text="Price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/sort_price"
android:layout_weight="1"
android:onClick="PriceSortClick"/>
<Button
android:text="Year"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/sort_year"
android:layout_weight="1"
android:onClick="YearSortClick"/>
</LinearLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/list_view"
android:smoothScrollbar="true"/>
My Custom Adapter:
public class CustomAdapter extends BaseAdapter {
String [] result1;
String [] result2;
String [] result3;
Context context;
private static LayoutInflater inflater=null;
public CustomAdapter(ListViewActivity mainActivity, String[] priceOrderList, String [] timeOrderList, String [] yearOrderList) {
// TODO Auto-generated constructor stub
result1=priceOrderList;
result2=timeOrderList;
result3=yearOrderList;
context=mainActivity;
inflater = ( LayoutInflater )context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return result1.length;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public class Holder
{
TextView tv;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Holder holder=new Holder();
View rowView;
rowView = inflater.inflate(R.layout.row_layout, null);
holder.tv=(TextView) rowView.findViewById(R.id.price_row);
holder.tv.setText(result1[position]);
holder.tv=(TextView) rowView.findViewById(R.id.time_row);
holder.tv.setText(result2[position]);
holder.tv=(TextView) rowView.findViewById(R.id.year_row);
holder.tv.setText(result3[position]);
rowView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(context, "You Clicked "+result1[position], Toast.LENGTH_LONG).show();
}
});
return rowView;
}
My ListView Activitiy(or activity where i inflate my custom listview):
public class ListViewActivity extends Activity implements View.OnClickListener {
ListView view_list;
Context context;
ArrayList priceOrder;
public static String [] priceOrderList={"50$","100$","120$","40$"};
public static String [] timeOrderList={"10min","12min","5min","4min"};
public static String [] yearOrderList={"2010","2011","2012","2004"};
private Button mTimeButton;
private Button mPriceButton;
private Button mYearButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view);
context=this;
mTimeButton = (Button) findViewById(R.id.sort_time);
mPriceButton = (Button) findViewById(R.id.sort_price);
mYearButton = (Button) findViewById(R.id.sort_year);
view_list = (ListView) findViewById(R.id.list_view);
view_list.setAdapter(new CustomAdapter(this, priceOrderList, timeOrderList, yearOrderList));
mTimeButton.setOnClickListener(this);
mPriceButton.setOnClickListener(this);
mYearButton.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onClick(View v) {
if (v == mPriceButton){
String pricesort = ("Sorting for Price");
Toast.makeText(ListViewActivity.this, pricesort, Toast.LENGTH_SHORT).show();
Comparator<String> StringAscComparator = new Comparator<String>() {
public int compare(String app1, String app2) {
String stringName1 = app1;
String stringName2 = app2;
return stringName1.compareToIgnoreCase(stringName2);
}
};
Collections.sort(Arrays.asList(priceOrderList), StringAscComparator);
} else if (v == mTimeButton){
String timesort = ("Sorting for Time");
Toast.makeText(ListViewActivity.this, timesort, Toast.LENGTH_SHORT).show();
Comparator<String> StringAscComparator = new Comparator<String>() {
public int compare(String app1, String app2) {
String stringName1 = app1;
String stringName2 = app2;
return stringName1.compareToIgnoreCase(stringName2);
}
};
Collections.sort(Arrays.asList(timeOrderList), StringAscComparator);
} else if (v == mYearButton){
String yearsort = ("Sorting for Year");
Toast.makeText(ListViewActivity.this, yearsort, Toast.LENGTH_SHORT).show();
Comparator<String> StringAscComparator = new Comparator<String>() {
public int compare(String app1, String app2) {
String stringName1 = app1;
String stringName2 = app2;
return stringName1.compareToIgnoreCase(stringName2);
}
};
Collections.sort(Arrays.asList(yearOrderList), StringAscComparator);
}
}
Anyways, thanks for the help! It's much appreciated!
In his comment, #Selvin suggests using a POJO to associate your data, and that's a great idea. It's best to find appropriate data types for your data:
public class Item {
public BigDecimal price; // why BigDecimal? http://stackoverflow.com/a/8148773/4504191
public Duration time; // this is from the new java.time API in v8
public int year; // java.time also has a Year class
}
A proper class would have private fields with setters and getters (left as an exercise for the reader).
Now you just have a List<Item> in your adapter.
These data types will also make your comparison logic a little easier.
There's so many different ways you could do this. I think what I would do is create a method on the adapter to sort the list, specifying a comparator:
public void sortUsing(Comparator<Item> comparator) {
Collections.sort(list, comparator);
notifyDataSetChanged();
}
Then I would create three different comparators — one for each field — and pass the appropriate comparator when the corresponding sort button is pressed. Here's the time version:
Comparator<Item> timeComparator = new Comparator<Item> {
#Override
int compare(Item lhs, Item rhs) {
return lhs.time.compareTo(rhs.time);
}
}
Write a method to sort your array. Add one more parameter to your adapter constructor .onClick of btn assign the adapter again like
view_list.setAdapter(new CustomAdapter(this, priceOrderList, sortArray(timeOrderList), yearOrderList,2));
based on the the new param assign the values into listview from adapter.
ps: sorry for writing comment this here , low rep :)
This code works in basic Activity, but it doesn't in Tabbed activity.
I want to use the ListView with custom view.
Common code:
list_row.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/textView2" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/textView3" />
</LinearLayout>
It is my simple data class, I want to show it:
String nev;
String szakma;
public String getNev() {
return nev;
}
public void setNev(String nev) {
this.nev = nev;
}
public String getSzakma() {
return szakma;
}
public void setSzakma(String szakma) {
this.szakma = szakma;
}
public Adat(String nev, String szakma) {
this.nev = nev;
this.szakma = szakma;
}
And my custom ListAdapter:
public class EgyeniAdapter extends BaseAdapter {
Context context;
ArrayList<Adat> adatok;
public EgyeniAdapter(Context context, ArrayList<Adat> adatok) {
this.context = context;
this.adatok = adatok;
}
#Override
public int getCount() {
return adatok.size();
}
#Override
public Object getItem(int position) {
return adatok.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_row,null); // itt rendelem hozza a saját viewet
if (convertView != null)
{
TextView Cim = (TextView) convertView.findViewById(R.id.textView2);
TextView Alcim = (TextView) convertView.findViewById(R.id.textView3);
Adat adatom = adatok.get(position);
Cim.setText(adatom.getNev());
Alcim.setText(adatom.getSzakma());
}
return convertView;
}
}
And it is my MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
...
betolt();
}
private void betolt()
{
ArrayList<Adat> adataim = new ArrayList<>();
adataim.add(new Adat("Title","Subtitle"));
adataim.add(new Adat("Title2","Subtitle2"));
final ListView myList= (ListView) findViewById(R.id.listView);
EgyeniAdapter egyeniAdapter = new EgyeniAdapter(this,adataim);
myList.setAdapter(egyeniAdapter);
}
This works, but when I want use it in another application in Tabbed activity, it throws:
NullPointerException: Attempt to invoke virtual method 'void
android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a
null object reference
What is the problem?
My fragment code:
<FrameLayout 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"
tools:context="com.example.mpet8.englishtest.Tesztek">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment"
android:id="#+id/tesztek_label"
/>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tesztek_listView"
android:layout_gravity="left|top" />
</FrameLayout>
I call my method in onStart method:
#Override
protected void onStart() {
super.onStart();
betolt();
}
in betolt() you are looking for a ListView with the id R.id.listView (final ListView myList= (ListView) findViewById(R.id.listView);) but in your fragmentlayout it has the id android:id="#+id/tesztek_listView"
album art with cursor and base adapter not showing in list or toast
i am trying to display the album art and album details in a listview however neither does it display in toast or in listview
here is the code
mainactivity
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//retrieveAudioFiles();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressLint("NewApi")
public void retrieveAudioFiles(){
SongsList songsList = new SongsList();
//Uri sd = Audio.Media.INTERNAL_CONTENT_URI ;
//Uri sd = Audio.Media.EXTERNAL_CONTENT_URI;
Uri sd = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;
String[] cols = {Audio.Media.TITLE,Audio.Media.ARTIST,Audio.Media.ALBUM};
String where = Audio.Media.IS_MUSIC;
Cursor audioCursor = getContentResolver().query(sd,cols,where,null,null);
while (audioCursor.moveToNext()){
int posColTitle = audioCursor.getColumnIndex(Audio.Media.TITLE);
int posColArtist = audioCursor.getColumnIndex(Audio.Media.ARTIST);
int posColAlbum = audioCursor.getColumnIndex(Audio.Media.ALBUM);
String songTitle = audioCursor.getString(posColTitle);
String songArtist = audioCursor.getString(posColArtist);
String songAlbum = audioCursor.getString(posColAlbum);
int posColId = audioCursor.getColumnIndex(Audio.Media._ID);
long songId = audioCursor.getLong(posColId);
Uri songUri = ContentUris.withAppendedId(Audio.Media.EXTERNAL_CONTENT_URI,songId);
String[] dataColumn = {Audio.Media.DATA};
Cursor coverCursor = getContentResolver().query(songUri, dataColumn, null, null, null);
coverCursor.moveToFirst();
int dataIndex = coverCursor.getColumnIndex(Audio.Media.DATA);
String filePath = coverCursor.getString(dataIndex);
coverCursor.close();
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(filePath);
byte[] coverBytes = retriever.getEmbeddedPicture();
Bitmap songCover;
Toast.makeText(getApplicationContext(),audioCursor.getString(audioCursor
.getColumnIndex(android.provider.MediaStore.Audio.Albums.ALBUM)),
Toast.LENGTH_LONG).show();
if (coverBytes!=null) //se l'array di byte non è vuoto, crea una bitmap
songCover = BitmapFactory.decodeByteArray(coverBytes, 0, coverBytes.length);
else
songCover=null;
songsList.add(new Song(songTitle,songArtist,songAlbum));
}
audioCursor.close();
}
public class SongsAdapter extends BaseAdapter {
private SongsList songsList;
private LayoutInflater songInf;
public SongsAdapter(Context c, SongsList theSongs){
super();
songsList=theSongs;
songInf=LayoutInflater.from(c);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return songsList.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return songsList.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
RowWrapper wrapper;
if (convertView == null)
{
convertView = songInf.inflate(
R.layout.song_row, null);
wrapper = new RowWrapper(convertView);
convertView.setTag(wrapper);
}
else
{
wrapper = (RowWrapper) convertView.getTag();
}
Song song = (Song) getItem(position);
wrapper.populate(song);
return convertView;
}
private class RowWrapper
{
private TextView titleTextView;
private TextView artistTextView;
private TextView albumTextView;
private ImageView coverImageView;
public RowWrapper(View convertView)
{
titleTextView = (TextView) convertView.findViewById(R.id.textTitle);
artistTextView = (TextView) convertView.findViewById(R.id.textArtist);
albumTextView = (TextView) convertView.findViewById(R.id.textAlbum);
coverImageView = (ImageView) convertView.findViewById(R.id.smallCover);
}
public void populate(Song song)
{
titleTextView.setText(song.title);
artistTextView.setText(song.artist);
albumTextView.setText(song.album);
if (song.cover != null)
coverImageView.setImageBitmap(song.cover);
}
}
}
}
then in the song class
public class Song {
public String title="";
public String artist="";
public String album="";
public Bitmap cover=null;
public Song(String t, String ar, String al){
title=t;
artist=ar;
album=al;
//cover=c;
}
public Song(){
}
}
and songList class
public class SongsList extends ArrayList<Song> {
public SongsList(){
super();
}
}
how ever nothing is displayed
here are the xml files
activty_main
<RelativeLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.stackalbumart.MainActivity" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
</ListView>
</RelativeLayout>
and song_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:onClick="songPicked" >
<ImageView
android:id="#+id/smallCover"
android:layout_width="60dp"
android:layout_height="60dp"
android:contentDescription="coverDescription"
android:src="#drawable/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/labelTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="labelTitle" />
<TextView
android:id="#+id/textTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:text="textTitle" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/labelArtist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:text="labelArtist" />
<TextView
android:id="#+id/textArtist"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:text="textArtist" />
<TextView
android:id="#+id/labelAlbum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="labelAlbum" />
<TextView
android:id="#+id/textAlbum"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:text="textAlbum" />
</LinearLayout>
</LinearLayout>
the app just opens and there is a blank white screen there is even no error
what really should be done
Since you are handle cursor, I would strongly suggest you to subclass CursorAdapter, which extends BaseAdapter and has the additional logic to handle the Cursor.
About your issue
in your retrieveAudioFiles(), after you close your cursor, you should instantiate the adapter and feed it to your ListView. E.g.
ListView listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(new SongsAdapter(this, songList));