How to make ListView items clickable? - java

I am wondering how to make ListView items clickable. And when pressed on item it sends you to another activity.
Here is my java coding:
public class Cantos extends AppCompatActivity {
ListView lv;
SearchView sv;
String[] cantos={"1: Abre Tu Oido", "2: A Cristo Quiero", "3: Acerquese Mi Clamor", "4: A Cristo Yo Alabare",
"5: Acude Dios", "6: Adelante", "7: A Dios Canto", "8: Adios Para Siempre", "9: Ahora Senor", "10: A Jesucristo Ven",
"11: Alabad A Dios" };
ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cantos);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setLogo(R.mipmap.ic_launcher);
toolbar.setTitle("Cantos");
lv = (ListView) findViewById(R.id.listView);
sv = (SearchView) findViewById(R.id.searchView);
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, cantos);
lv.setAdapter(adapter);
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String text) {
return false;
}
#Override
public boolean onQueryTextChange(String text) {
adapter.getFilter().filter(text);
return false;
}
});
}
}
Here is XML coding:
<RelativeLayout 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:background="#E0E0E0"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.ccb.lldm.lldmhimnario.Cantos">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:elevation="25dp"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimaryDark"
app:popupTheme="#style/AppTheme.PopupOverlay" />
<SearchView
android:layout_width="match_parent"
android:id="#+id/searchView"
android:queryHint="Busque Canto..."
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
</SearchView>
<ListView
android:layout_width="match_parent"
android:id="#+id/listView"
android:layout_height="wrap_content"
android:layout_below="#+id/searchView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true">
</ListView>
</RelativeLayout>
Thank You in advance.
P.s How can I change the font for the ListView items and color?
Thank you!

Use listview's OnItemClickListener
lv.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position,
long arg3)
{
// based on the item clicked go to the relevant activity
String clickedItem = (String)adapter.getItemAtPosition(position);
}
});

Use this code make clickable listview.
lv = (ListView) findViewById(R.id.listView);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView <? > arg0, View view, int position, long id) {
// When clicked, show a toast with the TextView text
Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
Toast.LENGTH_SHORT).show();
}
});

Related

"ArrayAdapter requires the resource ID to be a TextView" error for AndroidX

I have one problem to use ListView.
I search on the stackOverflow and other sites, but not fix again.
Genel.java:
public class Genel extends AppCompatActivity {
MediaController mediaController;
VideoView videoview;
ListView listView;
ArrayList<String> videoList;
ArrayAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_genel);
final VideoView videoview = findViewById(R.id.Videogenel);
listView = (ListView) findViewById(R.id.lgvideo);
videoList= new ArrayList<>();
videoList.add("Genel Bilgiler");
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.activity_list_item,videoList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (position){
case 0:
videoview.setVideoPath("/storage/A6D3-E544/videos/genel1.mp4");
break;
}
final MediaController mediacontroller = new MediaController(Genel.this);
mediacontroller.setAnchorView(videoview);
videoview.setMediaController(mediacontroller);
videoview.requestFocus();
videoview.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
#Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
videoview.setMediaController(mediacontroller);
mediacontroller.setAnchorView(videoview);
}
});
}
});
videoview.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.d("API123", "What " + what + " extra " + extra);
return false;
}
});
videoview.setMediaController(mediaController);
videoview.start();
}
});
XML file:
<VideoView
android:id="#+id/Videogenel"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:layout_gravity="center"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="76dp" />
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/lgvideo"
android:layout_below="#+id/Videogenel"
android:layout_centerHorizontal="true">
</ListView>
activity_main.xml:
<RelativeLayout 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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
When I use the android.R.layout.simple_list_item_1 everything works fine, with the own xml file I get "java.lang.IllegalStateException: ArrayAdapter requires the resource ID to be a TextView".
I need suggestions pls.
use: ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,R.layout.support_simple_spinner_dropdown_item,videoList);
instead of the: ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.activity_list_item,videoList);
remove android in android.R.layout.activity_list_item, and use the support_simple_spinner_dropdown_item instead of the activity_list_item.

How to change font color or size of Listview item

I'm looking for solution to my Listview where I would like to change the font color to red and size to any desired size of listview items.
I've tried using adaper but I'm countering multiple error.
Here is the xml file
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
app:title="Space Time Alarm"
android:layout_height="56dp"
android:background="#30e410"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<ListView
android:id="#+id/listView_Alarms"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="?android:attr/actionBarSize"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</android.support.constraint.ConstraintLayout>
and Mainactivity file is
public class MainActivity extends AppCompatActivity {
public static boolean havePermission;
private ListView listView_Alarms;
private FloatingActionButton button_NewAlarm;
private Toolbar toolbar;
private DatabaseManager databaseManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d("SPACESTOREALARM", "CREATING");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//setting up the toolbar and support
toolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(toolbar);
listView_Alarms = (ListView) findViewById(R.id.listView_Alarms);
SpaceTimeAlarmManager.getInstance().initializeSpaceTimeAlarmManager(this);
databaseManager = DatabaseManager.getInstance(this);
databaseManager.initialize(this, listView_Alarms);
listView_Alarms.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
SpaceTimeAlarm alarm = (SpaceTimeAlarm) listView_Alarms.getItemAtPosition(position);
createOrEditAlarm(alarm);
}
});
}
}
Here list view contains list of alarms but due to same color both of font and background..the list cannot be seen. So I need help to change font color and size of listview items of above.
Thanks in advance.
I would recommend to create a custom ListView.
Check this for creating a custom ListView
With a custom ListView you have got a lot of more options to customize it.
You can set an adapter and change the background color and item size like below:
lv = findViewById(R.id.listView);
lv.setAdaptater(adapter);
final ArrayAdapter<String> adapter = new ArrayAdapter<String> (this, android.R.layout.simple_list_item_1, list) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the current item from ListView
View view = super.getView(position, convertView, parent);
// Set the text color of TextView (ListView Item)
TextView tv = view.findViewById(android.R.id.text1);
// Generate ListView Item using TextView
tv.setTextColor(Color.parseColor("#efefef"));
tv.setTextSize(20);
tv.setAllCaps(true);
// Set a background color for ListView
view.setBackgroundColor(Color.parseColor("#00afd8"));
return view;
}
};
lv.setAdapter(adapter);
You can even alternate background colors.

Efficient way to display data

I am creating an app that has a fragment where a user can open a spinner using a button and select a food item. The food item will then be displayed under the button in a list. I have tried creating textviews and making invisible textviews and setting the text later, but none have worked. I was wondering if anyone knew of a better way of creating this that I'm not seeing.
<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.lastineindustries.ingredismartv2.Kitchen">
<!-- TODO: Update blank fragment layout -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:text="Add An Ingredient"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/add"
android:textSize="30sp"
android:layout_gravity="center" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="320dp"
android:layout_height="match_parent"
android:id="#+id/main"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:layout_width="60dp"
android:layout_height="match_parent"
android:id="#+id/valueButton"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
</LinearLayout>
Is this what you want?
Then, read my code.
code of ChooseFoodFragment.java and its layout file:
public class ChooseFoodFragment extends Fragment{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_choose_food, container, false);
initViews(v);
return v;
}
private Button btn_add;
private ListView listView;
private List<String> mData = new ArrayList<>();
private ArrayAdapter<String> mAdapter;
private void initViews(View v) {
listView = v.findViewById(R.id.list);
mAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, mData);
listView.setAdapter(mAdapter);
btn_add = v.findViewById(R.id.add);
btn_add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ChooseFoodDialog dialog = new ChooseFoodDialog();
dialog.setOnSelectedListener(new ChooseFoodDialog.OnSelectedListener() {
#Override
public void onSelected(String name) {
mData.add(name);
mAdapter.notifyDataSetChanged();// update the list of selected food
}
});
dialog.show(getFragmentManager(), "");//show the spinner items to select
}
});
}
}
fragment_choose_food.xml,just remove other views except the root view and the button, then add a ListView.
<?xml version="1.0" encoding="utf-8"?>
<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.lastineindustries.ingredismartv2.Kitchen">
<!-- TODO: Update blank fragment layout -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Add An Ingredient"
android:textSize="30sp" />
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp" />
</LinearLayout>
</FrameLayout>
the code of ChooseFoodDialog.java and its layout file.
public class ChooseFoodDialog extends DialogFragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = LayoutInflater.from(getContext()).inflate(R.layout.dialog_choose_food, container, false);
initViews(v);
return v;
}
private ListView lv;
private List<String> mData = new ArrayList<>();
private void initViews(View v) {
// prepare some temp data
for (int i = 0; i < 10; i++) {
mData.add("Ingredients_" + i);
}
lv = v.findViewById(R.id.lv_ingredients);
ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1, mData);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String ingredient = mData.get(i);
if (mListener != null) {
mListener.onSelected(ingredient);// when the item of food is selected
}
dismiss();
}
});
}
private OnSelectedListener mListener;
public void setOnSelectedListener(OnSelectedListener listener) {
mListener = listener;
}
interface OnSelectedListener {
void onSelected(String name);
}
}
dialog_choose_food.xml,that's simple.
<?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">
<ListView
android:id="#+id/lv_ingredients"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
run the program, check it.
You should use ListView or RecyclerView for such tasks. Check out example from official Android documentation: link.

Getting a Null Object Reference when trying to set imageview resource with checkbox

So I have an app with a listview. When you click a listview item it opens a new activity. I placed a checkbox in this new activity where when its checked, it should put a checkmark next to the listview item on the previous screen. I'm running into this error I'm guessing because I'm trying to set the checkbox from the second activity that has a different content view than the listview. I hope I explained that well.
Heres my RouteDetails.java with the checkbox code
public class RouteDetails extends AppCompatActivity {
ImageView routeImage;
String routeName;
CheckBox routeCheckBox;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_route_details);
//back button for route details view
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
///////checkbox///////////////////////////////////////////
routeCheckBox = (CheckBox) findViewById(R.id.routeCheckBox);
final ImageView checkImageView = (ImageView) findViewById(R.id.checkImageView);
routeCheckBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View view)
{
if (routeCheckBox.isChecked())
{
checkImageView.setImageResource(R.drawable.birdsboroicon);
}
}
});
/////////////////////////////////////////////
//sets actionbar title
routeName = getIntent().getExtras().getString("routeName");
getSupportActionBar().setTitle(routeName);
//TextView for route details
final TextView routeDetailsView = (TextView) findViewById(R.id.routeDetailsView);
routeDetailsView.setText(getIntent().getExtras().getCharSequence("route"));
//ImageView for route details
routeImage = (ImageView) findViewById(R.id.routeImage);
final int mImageResource = getIntent().getIntExtra("imageResourceId", 0);
routeImage.setImageResource(mImageResource);
and heres the custom_row.xml that contains the imageview im trying to set based on the checkbox state.
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="51dp"
android:id="#+id/routeText"
android:layout_weight="1"
android:textSize="18sp"
android:gravity="center_vertical"
android:textColor="#android:color/black"
android:typeface="normal"
/>
<ImageView
android:layout_width="35dp"
android:layout_height="35dp"
android:id="#+id/checkImageView" />
So I want the checkmark to be next to the listview item after the back button is pressed.
Ill include this other code if it is relavent
heres my RouteDetails.xml that contains the checkbox
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_route_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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.zach.listview.RouteDetails">
<CheckBox
android:text="Route Climbed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/routeCheckBox"
android:gravity="center" />
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/routeDetailsView"
android:textSize="18sp"
android:textAlignment="center"
android:textColor="#android:color/black"
android:layout_below="#id/routeCheckBox"/>
<ImageView
android:layout_below="#id/routeDetailsView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/routeImage"
android:scaleType="fitCenter"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:adjustViewBounds="true" />
</RelativeLayout>
</ScrollView>
My Custom adapter.java which creates each listview row
class CustomAdapter extends ArrayAdapter<CharSequence>{
public CustomAdapter(Context context, CharSequence[] routes) {
super(context, R.layout.custom_row ,routes);
}
#NonNull
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater routeInflater = LayoutInflater.from(getContext());
View customView = convertView;
if(customView == null){customView = routeInflater.inflate(R.layout.custom_row, parent, false);}
CharSequence singleRoute = getItem(position);
TextView routeText = (TextView) customView.findViewById(R.id.routeText);
routeText.setText(singleRoute);
return customView;
}
my mainavtivity.java which is where the listview is populated
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Action Bar customization
final android.support.v7.app.ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayOptions(android.support.v7.app.ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setCustomView(R.layout.actionbar);
setContentView(R.layout.activity_main);
///// fill listview numbers I want to add
final String[] routeListviewNumbers = getResources().getStringArray(R.array.routeNumbers);
//fill list view with xml array of routes
final CharSequence[] routeListViewItems = getResources().getTextArray(R.array.routeList);
//fills route detail text view with xml array info
final CharSequence[] routeDetail= getResources().getTextArray(R.array.routeDetail);
//fills route detail image view with xml array of images
final TypedArray image = getResources().obtainTypedArray(R.array.routeImages);
//image.recycle();
//custom adapter for list view
ListAdapter routeAdapter = new CustomAdapter(this, routeListViewItems);
final ListView routeListView = (ListView) findViewById(R.id.routeListView);
routeListView.setAdapter(routeAdapter);
routeListView.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
CharSequence route = routeListViewItems[position];
int imageId = (int) image.getResourceId(position, -1);
if (route.equals(routeListViewItems[position]))
{
Intent intent = new Intent(view.getContext(), RouteDetails.class);
intent.putExtra("route", routeDetail[position]);
intent.putExtra("imageResourceId", imageId);
intent.putExtra("routeName", routeListViewItems[position]);
startActivity(intent);
}
}
}
);
}
}
and my activitymain.xml which is the listview
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="0dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="0dp"
tools:context="com.example.zach.listview.MainActivity">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/routeListView"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
Edit: So I added this to my RouteDetails.java
routeCheckBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View view)
{
if (routeCheckBox.isChecked())
{
//checkImageView.setImageResource(R.drawable.checkmark);
Intent check = new Intent(RouteDetails.this,CustomAdapter.class);
check.putExtra("checkImageResource", R.drawable.checkmark);
startActivity(check);
}
}
});
and this to my customAdapter.java
////////trying to set checkmark/////
ImageView checkImageView = (ImageView) customView.findViewById(R.id.checkImageView);
checkImageView.setImageResource(((Activity) getContext()).getIntent().getIntExtra("checkImageResource",0));
////////////////////////////////////////
but this is not working either. It says fatal exception unable to find explicit activity class. It's doing this I guess since CustomAdapter is not an activity, but customadapter is linked to my custom_row which contains the imageview I want to add the checkbox to. How would I do this? I'm not sure what else to try
Edit: I still haven't found a solution if anyone has any suggestions!

Why imageButton in a ListView does not toggle untill scrolled?

I have a simple listView via a custom adapter. Each row in the list view is composed of a ImageButton and TextView.
The idea is to change the ImageButton when user taps on it and it does not work. However, ImageButton changes for the views that are scrolled and recycled. I mean, when user scrolls down the list and comes back to the top and tap on the ImageButton it works as expected for those rows that were scrolled and back again.
Can you guys help me out what i'm missing? I'm extremely new to Android and have been stuck around this for about a week now trying to fix this.
Here's the APK for the sample test app:
https://www.dropbox.com/s/pzlahtqkgj010m8/app-ListViewExample.apk?dl=0
Here are the relevant parts of my code:
avtivity_main.xml
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
/>
</RelativeLayout>
and to render the single row in the ListView the following xml is utilized:
single_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageButton"
android:src="#drawable/b"
android:layout_weight="2"
style="#style/ListView.first"
android:layout_gravity="center"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/textView"
android:layout_weight="10"
android:layout_gravity="center"
/>
</LinearLayout>
coming to the Java code,
MainActivity.java is
public class MainActivity extends AppCompatActivity {
String[] titles;
ListView list;
private listViewAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Resources res = getResources();
titles = res.getStringArray(R.array.titles);
list = (ListView) findViewById(R.id.listView);
adapter = new listViewAdapter(this, titles);
list.setAdapter(adapter);
}
}
and the custom adapter listViewAdapter.java look like this
class sListItem {
public ImageButton button;
public TextView text;
public boolean active;
}
public class listViewAdapter extends ArrayAdapter<String> {
private final String[] titles;
Context context;
private int size = 15;
public sListItem mp[] = new sListItem[size];
public listViewAdapter(Context context, String[] titles) {
super(context, R.layout.single_row, R.id.imageButton, titles);
this.context = context;
this.titles = titles;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.single_row, parent, false);
if(mp[position] == null)
mp[position] = new sListItem();
mp[position].button = (ImageButton) row.findViewById(R.id.imageButton);
mp[position].button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mp[position].active = !mp[position].active;
setIcon(position, mp[position].active);
}
});
mp[position].text = (TextView) row.findViewById(R.id.textView);
mp[position].text.setText(titles[position]);
setIcon(position, mp[position].active);
return row;
}
private void setIcon(int position, boolean active) {
Drawable drawable;
if(active){
drawable = getContext().getResources().getDrawable(R.drawable.a);
} else {
drawable = getContext().getResources().getDrawable(R.drawable.b);
}
mp[position].button.setImageDrawable(drawable);
}
}
EDIT: Added link to sample test app.
You should tell adapter to update by calling notifydatasetchanged in the click listener
mp[position].button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mp[position].active = !mp[position].active;
setIcon(position, mp[position].active);
notifydatasetchanged();
}
});

Categories

Resources