The problem is when the ListView loses focus, the selected item isn't highlighted.
I use a custom ArrayAdapter which uses the following layout for items:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ListTextBox"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="#dimen/Padding"
android:textSize="#dimen/TextSize"
/>
The ListSelector is a simple Shape drawable.
Thank you
edit...
Here is the ArrayAdapter:
listWords = new ArrayList<String>();
arrayAdapter = new DictListAdapter(this, R.layout.listtext, listWords);
list.setAdapter(arrayAdapter);
and the code for DictListAdapter:
public class DictListAdapter extends ArrayAdapter<String> {
public DictListAdapter(Context context, int textViewResourceId,
List<String> objects) {
super(context, textViewResourceId, objects);
this.context = (MainWindow) context;
this.objects = objects;
this.res = textViewResourceId;
}
Typeface font;
private List<String> objects;
private final MainWindow context;
int res;
int gravity=Gravity.LEFT;
#Override
public int getCount() {
return objects.size();
}
#Override
public String getItem(int position) {
return objects.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String obj = objects.get(position);
TextView tv = new TextView(context, null, res);
tv.setText(obj);
tv.setTypeface(context.getFont());
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX,
context.getResources().getDimension(R.dimen.TextSize));
tv.setGravity(gravity);
return tv;
}
public void setGravity(int g){
this.gravity=g;
}
}
i guess you have created array adapter in the following manner. if i am correct use the following:
static final String[] color = new String[]{"red","green","blue"};
We need to use the setListAdapter(..) method of the ListActivity class to bid the two (data and view). Android provides many implementations of the ListAdapter. We will use the simple ArrayAdapter.
What does the ArrayAdapter expect?
It expects the context object, the row layout and the data in an array.
So here it is:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, PENS));
getListView().setTextFilterEnabled(true);
}
use below code to show selected item
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Object o = this.getListAdapter().getItem(position);
String pen = o.toString();
Toast.makeText(this, "You have chosen the color: " + " " + color, Toast.LENGTH_LONG).show();
}
The simplest way is to add android:background="?android:attr/activatedBackgroundIndicator" in the layout you use for the row
Related
I am using the following code to display images on ListView using BaseAdapter .The code displays images from inside drawable folder. But I want to modify the code so it displays remote images from following Array:
String flags[] ={"http://www.website.com/images/usa.png","http://www.website.com/images/china.png","http://www.website.com/images/australia.png","http://www.website.com/images/portugle.png","http://www.website.com/images/norway.png","http://www.website.com/images/new_zealand.png"};
Could an expert show me what part needs to be change.Thanks in advance.
MainActivity.java:
public class MainActivity extends Activity {
ListView simpleList;
String countryList[] = {"USA", "China", "australia", "Portugle", "Norway", "NewZealand"};
int flags[] = {R.drawable.usa, R.drawable.china, R.drawable.australia, R.drawable.portugle, R.drawable.norway, R.drawable.new_zealand};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
simpleList = (ListView) findViewById(R.id.simpleListView);
CustomAdapter customAdapter = new CustomAdapter(getApplicationContext(), countryList, flags);
simpleList.setAdapter(customAdapter);
simpleList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), "Hello " + countryList[position], Toast.LENGTH_LONG).show();
}
});
}
}
CustomAdapter.java:
Public class CustomAdapter extends BaseAdapter {
Context context;
String countryList[];
int flags[];
LayoutInflater inflter;
public CustomAdapter(Context applicationContext, String[] countryList, int[] flags) {
this.context = context;
this.countryList = countryList;
this.flags = flags;
inflter = (LayoutInflater.from(applicationContext));
}
#Override
public int getCount() {
return countryList.length;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = inflter.inflate(R.layout.activity_listview, null);
TextView country = (TextView) view.findViewById(R.id.textView);
ImageView icon = (ImageView) view.findViewById(R.id.icon);
country.setText(countryList[i]);
icon.setImageResource(flags[i]);
return view;
}
}
You need to:
1) Fetch those images in a separate thread, you can use volley, retrofit, robospice for this.
2) On the response of any of those methods from 1) you have to pass the list of values you obtained from the service to your adapter's constructor. You will need to create a POJO for the model, this structure will hold all the elements from the REST webservice.
3) It is recommended to use a viewholder for your listview's adapter, to avoid inflating the views again and again.
The easiest thing to do is use Glide or Picasso:
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = inflter.inflate(R.layout.activity_listview, null);
TextView country = (TextView) view.findViewById(R.id.textView);
ImageView icon = (ImageView) view.findViewById(R.id.icon);
country.setText(countryList[i]);
// Assuming flags is now the list of Strings of image urls
GlideApp.with(view.getContext()).load(flags[i]).into(icon);
return view;
}
you can also use some third party library like Picasso or Glide to load images right into your adapter's get view method
Picasso.with(this).load(flags[adapter's
position]).into(imageView);
same in glide.
here is simple tutorial https://www.simplifiedcoding.net/picasso-android-tutorial-picasso-image-loader-library/
I have a listview on which i am showing data from my database and now i want to delete row on the basis of button clicked which is associated with each row.
i am having exception in CustomAdapter class whenever i press Done button.
CursorAdapter code is this:
public class CustomAdapter extends CursorAdapter {
TextView task,daate;
Button del;
public static int id;
Context ct;
public CustomAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
// The newView method is used to inflate a new view and return it,
// you don't bind any data to the view at this point.
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
ct=context;
return LayoutInflater.from(context).inflate(R.layout.adapter, parent, false);
}
// The bindView method is used to bind all data to a given view
// such as setting the text on a TextView.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final DatabaseHelper help=new DatabaseHelper(ct);
del = (Button) convertView.findViewById(R.id.deleteBtn);
del.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
help.deleteRecordWithId(position);
}
}
);
return super.getView(position, convertView, parent);
}
#Override
public void bindView(View view, Context context, final Cursor cursor) {
// Find fields to populate in inflated template
task = (TextView) view.findViewById(R.id.dynamicTask);
daate = (TextView) view.findViewById(R.id.dynamicDate);
id=cursor.getInt(cursor.getColumnIndex("_id"));
String Task=cursor.getString(cursor.getColumnIndex("task"));
String Daate=cursor.getString(cursor.getColumnIndex("ddate"));
task.setText(Task);
daate.setText(Daate);
}
}
and my database function deleteRecordWithId() is:
public boolean deleteRecordWithId(int id) {
SQLiteDatabase db=this.getWritableDatabase();
long rows=db.delete(TABLE_NAME,"_id=?",new String[] {String.valueOf(id)});
if(rows>0) {
return true;
}
else {
return false;
}
}
and i am getting this exception:
java.lang.NullPointerException: Attempt to invoke virtual method
'android.view.View android.view.View.findViewById(int)' on a null object
reference
What is wrong in this code. please help me to rectify it.
Replace this:
help.deleteRecordWithId(position);
with:
CustomAdapter.this.remove(CustomAdapter.this.getItem(position));
CustomAdapter.this.notifyDataSetChanged();
It will delete data from your adapter and notifydatasetchanged will update your listview accordingly.
First Method: You describe like that
public class CustomAdapter extends CursorAdapter {
TextView task,daate;
Button del;
public static int id;
Context ct;
public CustomAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
ct=context;
return LayoutInflater.from(context).inflate(R.layout.adapter, parent, false);
}
#Override
public void bindView(View view, Context context, final Cursor cursor) {
// Find fields to populate in inflated template
task = (TextView) view.findViewById(R.id.dynamicTask);
daate = (TextView) view.findViewById(R.id.dynamicDate);
id=cursor.getInt(cursor.getColumnIndex("_id"));
String Task=cursor.getString(cursor.getColumnIndex("task"));
String Daate=cursor.getString(cursor.getColumnIndex("ddate"));
task.setText(Task);
daate.setText(Daate);
final DatabaseHelper help=new DatabaseHelper(ct);
del = (Button) convertView.findViewById(R.id.deleteBtn);
}}
MainActivity:
public class MainActivity{
private CustomAdapter cursorAdapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cursorAdapter = new CustomAdapter(this, null);
}
public void deleteRecordWithId(View view) {
View parentRow = (View) view.getParent().getParent();
ListView listView = (ListView) view.getParent().getParent().getParent();
int position = listView.getPositionForView(parentRow);
long id = cursorAdapter.getItemId(position);
SQLiteDatabase db=this.getWritableDatabase();
long rows=db.delete(TABLE_NAME,"_id=?",new String[] {String.valueOf(id)});
if(rows>0) {
return true;
}
else {
return false;
}
}
}
and xml like that:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/task_outer_container"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:gravity="center_vertical"
android:background="#drawable/background_transparent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:clipChildren="false"
>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:id="#+id/delete_button"
android:onClick="deleteRecordWithId"
app:srcCompat="#drawable/remove_icon"
android:background="#drawable/background_transparent"
android:layout_gravity="center_vertical"
android:adjustViewBounds="false"
android:paddingStart="7dp"
android:paddingEnd="7dp"
android:layout_marginEnd="-5dp"/>
</RelativeLayout>
Second Method: You should not use getView in the Cursoradapter. You need to do all the operations in bindview. So uou can not reach id with getview.
For example: https://github.com/rodoggx/w4d1_Simple_CursorAdapter/blob/master/app/src/main/java/com/example/sqlitecursoradapter/CustomAdapter.java
set setOnItemClickListener to your listview...
yourListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
yourListView.remove(position);
database.removeItem(id);//create removemethod in database class
}
});
Define removeItem method
public void remove(long id){
String str =String.valueOf(id);
database.execSQL("DELETE FROM <TABLE_NAME> WHERE _id = '" + str + "'");
}
ListView doesn't give a straightforward way to implement actions to views inside an item. Use RecyclerView instead, it's more customizable and good for performance than the list view.
Create Lists and Cards - Android Developer
I don't know how to set the selected country isd code in
spinner.Below I have posted the code what I have been tried so far:
MainActivity.java:
public class MainActivity extends Activity implements OnItemSelectedListener {
ArrayList<String> arrCode;
ArrayList<String> arrCountry;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
arrCode = new ArrayList<>();
arrCountry = new ArrayList<>();
arrCountry.add("US");
arrCountry.add("KZ");
arrCountry.add("EG");
arrCountry.add("ZA");
arrCountry.add("GR");
arrCode.add("1");
arrCode.add("7");
arrCode.add("20");
arrCode.add("27");
arrCode.add("30");
ArrayAdapter<String> adapter_state = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, arrCountry);
adapter_state.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sp_mobile_code.setAdapter(adapter_state);
sp_mobile_code.setOnItemSelectedListener(this);
}
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
int spinnerValue1 = sp_mobile_code.getSelectedItemPosition();
String data = arrCode.get(spinnerValue1);
Log.e("data", "" + data);
sp_mobile_code.setPrompt(data);
/* sp_mobile_code.setSelection(position);*/
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
My issue is : I can't set the isd code in same spinner.If I have to
set isd code in textview means it will be easy.But I have to set it
in the spinner
Edit: spinner list showing correctly the country list.on clicking the country list, I have to show the isd code
Use Custom ArrayAdapter.
private static class CustomSpinnerAdapter extends ArrayAdapter<String>
{
List<String> arrCodes;
public CustomSpinnerAdapter(Context context, int resource, List<String> items, List<String> arrCodes)
{
super(context, resource, items);
this.arrCodes = new ArrayList<>();
this.arrCodes = arrCodes;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
TextView view = (TextView) super.getView(position, convertView, parent);
view.setText(arrCodes.get(position));
return view;
}
}
Check the position in the getView() and set text of your desire. Use this adapter for the Spinner
I would like to open an activity for each of my listview items. Done some research around onitemclickListener but don't know quite how to fit in with my current code.
My activities are called:
BhutanInfo.java
ColumbiaInfo.java
My listview is set up in an xml file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="country_names">
<item>Bhutan</item>
<item>Colombia</item>
</string-array>
<array name="country_icons">
<item>#drawable/bhutan</item>
<item>#drawable/colombia</item>
</array>
</resources>
In my class file I have the following:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Context ctx = getApplicationContext();
Resources res = ctx.getResources();
String[] options = res.getStringArray(R.array.country_names);
TypedArray icons = res.obtainTypedArray(R.array.country_icons);
setListAdapter(new ImageAndTextAdapter(ctx, R.layout.main_list_item, options, icons));
}
I also have another class which sets the adapter.
public class ImageAndTextAdapter extends ArrayAdapter<String> {
private LayoutInflater mInflater;
private String[] mStrings;
private TypedArray mIcons;
private int mViewResourceId;
public ImageAndTextAdapter(Context ctx, int viewResourceId,
String[] strings, TypedArray icons) {
super(ctx, viewResourceId, strings);
mInflater = (LayoutInflater)ctx.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
mStrings = strings;
mIcons = icons;
mViewResourceId = viewResourceId;
}
#Override
public int getCount() {
return mStrings.length;
}
#Override
public String getItem(int position) {
return mStrings[position];
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = mInflater.inflate(mViewResourceId, null);
ImageView iv = (ImageView)convertView.findViewById(R.id.option_icon);
iv.setImageDrawable(mIcons.getDrawable(position));
TextView tv = (TextView)convertView.findViewById(R.id.option_text);
tv.setText(mStrings[position]);
return convertView;
}
Any help would be appreciated.
if you had only two items means you can redirect the activity based on the position and you can perform this way
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String str = parent.getItemAtPosition(position).toString();
Log.e("Clicked Value is", str);
if(str.equals("<Your Class Name>")){
startActivity(new Intent(MainActivity.this,
FirstActivity.class);
}else{
startActivity(new Intent(MainActivity.this,
Second.class);
}
}
});
In this scenario you used custom adapter, i am right.
so you can manage click listener in custom adapter,
if you don't want this scenario, then you have to
android:focusableInTouchMode="false"
in you custom list row in xml file, and then call then listview onclick listener it will work.
in your ActivityClass, have the listView implement the onItemClickListener.
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String value = options[position];
if(value.equals("Bhutan")){
Intent intent = new Intent(CurrentActivity.this, BhutanInfo.class);
startActivity(intent);
}else if(value.equals("Columbia")){
intent = new Intent(CurrentActivity.this, ColumbiaInfo.class);
startActivity(intent);
}
}
});
P.S: Ensure that BhutanInfo and ColumbiaInfo are extending Activity.
And in the row layout inflating the listview set focusable and focusableInTouchMode to false for all the elements in it.
I have a listview in a fragment here is my current code for it:
public static class AllSectionFragment extends Fragment {
public static final String ARG_SECTION_NUMBER = "section_number";
public AllSectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tasks_all,
container, false);
// /////////////////////////////////////////////////////////////////
// Set up all components here:: ie text views , buttons lists etc.//
// that correspond to the layout fragment xml file //
////////////////////////////////////////////////////////////////////
TextView dummyTextView = (TextView) rootView
.findViewById(R.id.fragment_tasks_all_textView);
dummyTextView.setText(Integer.toString(getArguments().getInt(
ARG_SECTION_NUMBER)));
ArrayList<String> arrayList = new ArrayList<String>();
ListView allList = (ListView) rootView
.findViewById(R.id.fragment_tasks_all_list);
MyCustomAdapter mAdapter = new MyCustomAdapter(getActivity(),
arrayList); // Class to populate a ListView with an
// ArrayList
allList.setAdapter(mAdapter);
// Populate array list
for (int i = 0; i < 5; i++) {
arrayList.add(" All Task " + i);
}
mAdapter.notifyDataSetChanged();
return rootView;
}
public void onListItemClick(ListView l, View v, int position, long id) {
System.out.println("pos: "+ position);
}
}
and my layout.xml file
<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: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=".TasksActivity$DummySectionFragment" >
<TextView
android:id="#+id/fragment_tasks_all_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/fragment_tasks_all_list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="0.41"
android:cacheColorHint="#00000000"
android:clickable="true"
android:listSelector="#android:color/transparent"
android:transcriptMode="alwaysScroll" >
</ListView>
First of all. how can i make it so that i can click on an item in the list,
and second of all how do i add the onclick listener for it.
Why dont you just use ListFragment:
public static class ArrayListFragment extends ListFragment {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, Shakespeare.TITLES));
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.i("FragmentList", "Item clicked: " + id);
}
}
Use the alternative constructor for ArrayAdapter that allows you to specify a layout file to host your listview:
public ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
I had a similar issue and was resolved by creating a interface with onClick method and implementing it in fragment.
Try do this:
Create a interface:
MyOnViewClickListener.java
public interface MyOnViewClickListener {
public void myOnViewClickListener(View v);
}
In your custom adapter class, create a constructor passing MyOnViewClickListener as argument:
private Context context;
private MyOnViewClickListener itemListener;
private List<String> items;
public MyCustomAdapter(Context context, List<String> items, MyOnViewClickListener itemListener) {
this.itemListener = itemListener;
this.context = context;
this.items = items;
}
Inside getView() method, put:
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.your_row_layout, parent, false);
TextView textView1 = (TextView) row.findViewById(R.id.quizchallenge);
textView1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
itemListener.myOnViewClickListener(v);
}
});
Finally, in your fragment class, implement the new interface:
public class ListFriendFragment extends Fragment implements MyOnViewClickListener {
.
.
.
#Override
public void myOnViewClickListener(View v){
//call your method
quickQuiz();
}
Set up the adapter:
adapter = new MyCustomAdapter(getContext(), myItemsList, MyFragment.this);