I am having an listview with checkboxes,from the top i am giving an "select all",while check the select all,i want all checkbox has to select it.But now while checking the select all is not selecting all the checkbox.Seperate checkbox is working fine.
This is the layout for select all for listview.
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="right"
android:paddingRight="5dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/strAll"
/>
<CheckBox
android:id="#+id/chkAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
</RelativeLayout>
"ContactActivity.java"
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.get);
lv =(ListView)findViewById(R.id.lv);
getAllCallLogs(this.getContentResolver());
ma = new MyAdapter();
lv.setAdapter(ma);
lv.setOnItemClickListener(this);
lv.setItemsCanFocus(false);
lv.setTextFilterEnabled(true);
send = (Button) findViewById(R.id.button1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice,lv);
setListAdapter(adapter);
final CheckBox chkAll = ( CheckBox ) findViewById(R.id.chkAll);
chkAll.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
int size = 0;
boolean isChecked = chkAll.isChecked();
if (isChecked == true) {
size = lv.getCount();
for (int i = 0; i <= size; i++)
lv.setItemChecked(i, true);
} else if(isChecked==false)
{
size = lv.getCount();
for (int i = 0; i <= size; i++)
lv.setItemChecked(i, false);
}
}
});
send.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
StringBuilder checkedcontacts= new StringBuilder();
System.out.println(".............."+ma.mCheckStates.size());
for(int i = 0; i < name1.size(); i++)
{
if(ma.mCheckStates.get(i)==true)
{
phno0.add(phno1.get(i).toString()) ;
checkedcontacts.append(name1.get(i).toString());
checkedcontacts.append("\n");
}
else
{
System.out.println("..Not Checked......"+name1.get(i).toString());
}
}
Toast.makeText(ContactActivity.this, checkedcontacts,1000).show();
Intent returnIntent = new Intent();
returnIntent.putStringArrayListExtra("name",phno0);
setResult(RESULT_OK,returnIntent);
finish();
}
});
}
private void setListAdapter(ArrayAdapter<String> adapter1) {
// TODO Auto-generated method stub
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
ma.toggle(arg2);
}
public void getAllCallLogs(ContentResolver cr) {
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
while (phones.moveToNext())
{
String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
System.out.println(".................."+phoneNumber);
name1.add(name);
phno1.add(phoneNumber);
}
phones.close();
}
class MyAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener
{ private SparseBooleanArray mCheckStates;
LayoutInflater mInflater;
TextView tv1,tv;
CheckBox cb;
MyAdapter()
{
mCheckStates = new SparseBooleanArray(name1.size());
mInflater = (LayoutInflater)ContactActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return name1.size();
}
#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 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi=convertView;
if(convertView==null)
vi = mInflater.inflate(R.layout.row, null);
tv= (TextView) vi.findViewById(R.id.textView1);
tv1= (TextView) vi.findViewById(R.id.textView2);
cb = (CheckBox) vi.findViewById(R.id.checkBox1);
tv.setText("Name :"+ name1.get(position));
tv1.setText("Phone No :"+ phno1.get(position));
cb.setTag(position);
cb.setChecked(mCheckStates.get(position, false));
cb.setOnCheckedChangeListener(this);
return vi;
}
private int getCheckedItemCount(){
int cnt = 0;
SparseBooleanArray positions = lv.getCheckedItemPositions();
int itemCount = lv.getCount();
for(int i=0;i<itemCount;i++){
if(positions.get(i))
cnt++;
}
return cnt;
}
public boolean isChecked(int position) {
return mCheckStates.get(position, false);
}
public void setChecked(int position, boolean isChecked) {
mCheckStates.put(position, isChecked);
}
public void toggle(int position) {
setChecked(position, !isChecked(position));
}
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
// TODO Auto-generated method stub
mCheckStates.put((Integer) buttonView.getTag(), isChecked);
}
}
I am posting another answer. Please listen carefully.
1.) Create a global boolean variable :-
boolean flag = false;
2.)in your getView, do this. This will not check all the checkboxes in your listview. I am assuming that you have only one checkbox in your listview.
holder.checkBoxinyourListView.setChecked(flag);
3.) Now, in the listener of the checkbox which is NOT in your listview, add this code :-
checkBox not in listView.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
flag = !flag;
adapter.notifyDataSetChanged();
}
});
ScreenShot 1:- When not checked
ScreenShot 2:- When Checked
This Code Works 100%
NOTE :- In my project, i am using a lazy loader for images. Please don't get confused.
Jars in my project :- universal-image-loader-1.8.7 , android-support-v4
MainActivity.Class
package com.example.listviewwithselectallcheckbxox;
//import it.sephiroth.android.library.widget.AdapterView;
//import it.sephiroth.android.library.widget.AdapterView.OnItemClickListener;
//import it.sephiroth.android.library.widget.HListView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageLoadingListener;
import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;
public class MainActivity extends Activity{
DisplayImageOptions options;
ArrayList<Integer> checkedPositions = new ArrayList<Integer>();
boolean flag = false;
CheckBox selectAll;
private static final String LOG_TAG = "MainActivity";
ListView listView;
TestAdapter mAdapter;
List<RowItem> rowItems;
public static final String[] url = {"https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg",
"https://lh4.googleusercontent.com/--dq8niRp7W4/URquVgmXvgI/AAAAAAAAAbs/-gnuLQfNnBA/s1024/A%252520Song%252520of%252520Ice%252520and%252520Fire.jpg",
"https://lh5.googleusercontent.com/-7qZeDtRKFKc/URquWZT1gOI/AAAAAAAAAbs/hqWgteyNXsg/s1024/Another%252520Rockaway%252520Sunset.jpg",
"https://lh3.googleusercontent.com/--L0Km39l5J8/URquXHGcdNI/AAAAAAAAAbs/3ZrSJNrSomQ/s1024/Antelope%252520Butte.jpg",
"https://lh6.googleusercontent.com/-8HO-4vIFnlw/URquZnsFgtI/AAAAAAAAAbs/WT8jViTF7vw/s1024/Antelope%252520Hallway.jpg",
"https://lh4.googleusercontent.com/-WIuWgVcU3Qw/URqubRVcj4I/AAAAAAAAAbs/YvbwgGjwdIQ/s1024/Antelope%252520Walls.jpg",
"https://lh6.googleusercontent.com/-UBmLbPELvoQ/URqucCdv0kI/AAAAAAAAAbs/IdNhr2VQoQs/s1024/Apre%2525CC%252580s%252520la%252520Pluie.jpg",
"https://lh3.googleusercontent.com/-s-AFpvgSeew/URquc6dF-JI/AAAAAAAAAbs/Mt3xNGRUd68/s1024/Backlit%252520Cloud.jpg",
"https://lh5.googleusercontent.com/-bvmif9a9YOQ/URquea3heHI/AAAAAAAAAbs/rcr6wyeQtAo/s1024/Bee%252520and%252520Flower.jpg",
"https://lh5.googleusercontent.com/-n7mdm7I7FGs/URqueT_BT-I/AAAAAAAAAbs/9MYmXlmpSAo/s1024/Bonzai%252520Rock%252520Sunset.jpg",
"https://lh6.googleusercontent.com/-4CN4X4t0M1k/URqufPozWzI/AAAAAAAAAbs/8wK41lg1KPs/s1024/Caterpillar.jpg",
"https://lh3.googleusercontent.com/-rrFnVC8xQEg/URqufdrLBaI/AAAAAAAAAbs/s69WYy_fl1E/s1024/Chess.jpg"};
#Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.build();
ImageLoader.getInstance().init(config);
listView = (ListView) findViewById( R.id.hListView1 );
selectAll = (CheckBox) findViewById(R.id.selectall);
rowItems = new ArrayList<RowItem>();
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error)
.cacheInMemory(true)
.displayer(new RoundedBitmapDisplayer(0))
.cacheOnDisc(true)
.build();
for (int i = 0; i < url.length; i++) {
RowItem item = new RowItem(url[i]);
rowItems.add(item);
}
mAdapter = new TestAdapter(this,R.layout.list_item, rowItems);
listView.setHeaderDividersEnabled( true );
listView.setFooterDividersEnabled( true );
listView.setAdapter( mAdapter );
selectAll.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
flag = !flag;
mAdapter.notifyDataSetChanged();
}
});
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position,
long arg3) {
Toast.makeText(getApplicationContext(), position+"", Toast.LENGTH_SHORT).show();
CheckBox check = (CheckBox)view.findViewById(R.id.radio);
final Integer index = Integer.valueOf(position);
if(!checkedPositions.contains(index))
checkedPositions.add(index);
else
checkedPositions.remove(index);
check.setChecked(checkedPositions.contains(index));
}
});
Log.i( LOG_TAG, "choice mode: " + listView.getChoiceMode() );
}
public class TestAdapter extends ArrayAdapter<RowItem> {
private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
Context context;
protected ImageLoader imageLoader = ImageLoader.getInstance();
public TestAdapter(Context context, int resourceId,
List<RowItem> items) {
super(context, resourceId, items);
this.context = context;
}
/*private view holder class*/
private class ViewHolder {
ImageView imageView;
CheckBox radio1;
}
#Override
public int getViewTypeCount() {
return 3;
}
#Override
public int getItemViewType( int position ) {
return position%3;
}
ViewHolder holder=null;
#Override
public View getView(final int position, View convertView, ViewGroup parent ) {
RowItem rowItem = getItem(position);
holder = new ViewHolder();
final int i = position;
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.list_item, null);
holder.imageView = (ImageView) convertView.findViewById(R.id.icon);
holder.radio1 = (CheckBox) convertView.findViewById(R.id.radio);
convertView.setTag(holder);
}
else{
holder = (ViewHolder) convertView.getTag();
}
holder.radio1.setChecked(flag);
if(flag){
if(!checkedPositions.contains(position))
checkedPositions.add(position);
}
else
{
checkedPositions.clear();
}
final Integer index = Integer.valueOf(position);
holder.radio1.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton arg0, boolean isChecked) {
if(isChecked){
if(!checkedPositions.contains(index))
checkedPositions.add(index);
}
else
checkedPositions.remove(index);
}
});
imageLoader.displayImage(rowItem.getimageUrl(), holder.imageView, options, animateFirstListener);
holder.radio1.setChecked(checkedPositions.contains(index));
return convertView;
}
}
private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {
static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
if (loadedImage != null) {
ImageView imageView = (ImageView) view;
boolean firstDisplay = !displayedImages.contains(imageUri);
if (firstDisplay) {
FadeInBitmapDisplayer.animate(imageView, 5000);
displayedImages.add(imageUri);
}
}
}
}
}
RowItem.class
package it.sephiroth.listviewwithselectallcheckbxox;
public class RowItem {
private int imageId;
private String imageUrl;
public RowItem(int imageId) {
this.imageId = imageId;
}
public RowItem(String imageUrl) {
this.imageUrl = imageUrl;
}
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
public String getimageUrl() {
return imageUrl;
}
public void setimageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
}
activity_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:orientation="vertical"
tools:context=".MainActivity" >
<ListView
android:id="#+id/hListView1"
android:layout_width="match_parent"
android:layout_height="300dp"
android:paddingTop="20dip"
android:paddingBottom="20dip"
android:background="#11000000"
/>
<CheckBox
android:id="#+id/selectall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/hListView1"
android:layout_marginLeft="60dp"
android:layout_marginTop="64dp"
android:text="selectall" />
</RelativeLayout>
list_item.xml
<?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" >
<ImageView
android:id="#+id/icon"
android:layout_width="100dp"
android:layout_height="100dp"
android:contentDescription="ImageView"
android:paddingLeft="10dp"
android:paddingRight="10dp" >
</ImageView>
<CheckBox
android:id="#+id/radio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/icon"
android:layout_marginLeft="33dp"
android:focusable="false"
android:focusableInTouchMode="false" />
</RelativeLayout>
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.sephiroth.android.sample.horizontalvariablelistviewdemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:hardwareAccelerated="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
In the getView(), Add all the position of the checkboxes
ArrayList<Integer> addIndex= new ArrayList<Integer>();//Global
checkedPositions.add(position);
This will contain all the checkboxes position
Use a ArrayList to maintain all the checkbox states in the ListView to keep track of which checkbox is checked with a boolean.
Then when you click on checkAll CheckBox you update all boolean in your list to true and do yourAdapter.notifyDataSetChanged();
ArrayList<Integer> checkedPositions = new ArrayList<Integer>();//Global
Scenario : When Checking individual Checkboxes, adding in array list. The code below is to be added in ListView.setOnItemClickListener()
final Integer index = Integer.valueOf(position);
if(!checkedPositions.contains(index))
checkedPositions.add(index);
else
checkedPositions.remove(index);
check.setChecked(checkedPositions.contains(index));
Scenario 2 : When you check the SelectAll Checkbox.
holder.selectAllCheckbox.setOnCheckedChangeListener() listener
//Write your code here. Write an if condition that matches for the indexes in both the array list i have created and set checked as per your need
Note :- i have used an integer array list. You can use a boolean and do the same steps and the code below:-
if(list.get(position).isChecked()){
cellHolder.checkBox.setChecked(true);
}
else{
cellHolder.checkBox.setChecked(false);
}
All the boolean are at true so all the checkBoxes will be checked (the same logic goes for uncheck)
public class Adapter extends ArrayAdapter<TripItem> {
private final Context context;
private final ArrayList<CommonExpenseItem> tripExpenseItems;
public TripsAdapter(Context context, ArrayList<TripItem> values,
ArrayList<CommonExpenseItem> tripExpenses) {
super(context, R.layout.expense_list_row, values);
this.context = context;
this.tripExpenseItems = tripExpenses;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.expense_list_row, parent,
false);
return rowView;
}
}
The above is a simlple custom adapter ,here i am passing values in a arrayList u can pass hashmap simply,
Initially load all the string values in a separate hashmap or pojo obj with another value named as checkBox value as "disabled", and set the adapter ,
Then in the getView method set the name in the text view and get the checkbox string and check the checkbox if the value is enabled or uncheck if the value is disabled.
and also set tag the position to the checkbox, and create oncheckchange listener for the checkbox item inside the getView() and inside that method get the checkbox tag and get the respective hash map or the obj from the arrayList.
And Change the chekcbox value as enabled and notify the data set to be changed.
Finally for ur problem. once the checkbox in main layout is checked get the arraylist and in a for loop get the hash map or the objs and set the checkbox values to "enabled" and notify dataset changed or set a new adapter and populate in the list view. like wise u can get the solution as u required.
Related
When the edit button is clicked on my activity_main.xml it fires this method in my main activity.
public void editActivity(View view) {
editIds.clear();
//Check to see if any activities are ticked (checked) and grab the id if they are.
for (int i = 0; i < adapter.getCount(); i++) {
CheckBox c = listView.getChildAt(i).findViewById(R.id.checkBox);
if (c.isChecked()) {
editIds.add(adapter.getItemId(i));
}
}
//If only one item is checked start the Edit activity
if (editIds.size() == 1) {
Intent intent = new Intent(this, EditActivity.class);
intent.putExtra("ID", String.valueOf(editIds.get(0)));
startActivityForResult(intent, 2);
}
//If more than 1 or none are checked inform the user
else {
String output = "VIEW / EDIT: Please select one activity.";
Toast.makeText(this, output, Toast.LENGTH_SHORT).show();
}
}
This is checking for any checkboxes checked in the ListView. All works fine until the size of the ListView outgrows the size of the screen. What I mean is as soon as the list has to be scrolled clicking Edit causes the app to crash with this error:
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
at com.example.activitytracker.MainActivity.editActivity(MainActivity.java:108)
All works fine until the size of the list exceeds the size of the screen and some research has indicated that although my custom adapter contains all the entries for the entire list view the list view only stores the visible entries. I think this is why I get the error.
How can I populate the ArrayList editIds with the checked items id so I can either retrieve that record from the SQLite db or delete it.
My adapter:
package com.example.activitytracker;
import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.TextView;
public class ActivityAdapter extends CursorAdapter {
public ActivityAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.activity, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// Find fields to populate in inflated template
TextView activityTitle = (TextView) view.findViewById(R.id.activityTitle);
TextView activityDescription = (TextView) view.findViewById(R.id.activityDescription);
TextView activityDate = (TextView) view.findViewById(R.id.activityDate);
// Extract properties from cursor
String activity = cursor.getString(cursor.getColumnIndexOrThrow("activity"));
String description = cursor.getString(cursor.getColumnIndexOrThrow("description"));
String date = cursor.getString(cursor.getColumnIndexOrThrow("date"));
// Shorten description for cleaner screen display
String displayValueOfDescription = description;
if (description.length() > 20) {
displayValueOfDescription = description.substring(0, 19) + "...";
}
// Create UK date format for screen display
String yearDB = date.substring(0, 4);
String monthDB = date.substring(5, 7);
String dayDB = date.substring(8, 10);
String dateDB = dayDB + "-" + monthDB + "-" + yearDB;
// Populate fields with extracted properties
activityTitle.setText(activity);
activityDescription.setText(String.valueOf(displayValueOfDescription));
activityDate.setText(String.valueOf(dateDB));
}
public void update(Cursor cursor) {
this.swapCursor(cursor);
this.notifyDataSetChanged();
}
}
My layout_main.xml:
<?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"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="#style/AppTheme">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/activity"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="18sp"
android:textStyle="italic"
android:padding="5dp"
android:layout_weight="4"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/description"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="18sp"
android:textStyle="italic"
android:padding="5dp"
android:layout_weight="6"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/date"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="18sp"
android:textStyle="italic"
android:padding="5dp"
android:layout_weight="3"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.1">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme">
<Button
android:id="#+id/edit"
android:onClick="editActivity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/edit" />
<Button
android:id="#+id/delete"
android:onClick="deleteActivity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/delete" />
</LinearLayout>
</LinearLayout>
My ListView:
<?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">
<CheckBox
android:id="#+id/checkBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#null"
android:layout_weight="1"/>
<TextView
android:id="#+id/activityTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/activity"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="15sp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:layout_weight="3"/>
<TextView
android:id="#+id/activityDescription"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/description"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="15sp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:layout_weight="6"/>
<TextView
android:id="#+id/activityDate"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/date"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="15sp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:layout_weight="3"/>
</LinearLayout>
Any help is appreciated as I am a complete beginner with Android and Java.
Here is my onCreate()
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
dbManager = new DBManager(this);
dbManager.open();
adapter = new ActivityAdapter(this, dbManager.fetch());
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter);
}
EDIT
I have added this code to my Adapter
checked.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
// Do the stuff you want for the case when the row TextView is clicked
// you may want to set as the tag for the TextView the position paremeter of the `getView` method and then retrieve it here
Integer realPosition = (Integer) v.getTag();
// using realPosition , now you know the row where this TextView was clicked
Log.d("CLICKEDCHECK", "POS=" + v.getId());
}
});
Im logging the getId but this is the same no matter what tickbox i check. How do I get to the records id for that particular checkbox? Then I could add or remove them from an array list.
EDIT
Update with code from devgianlu.
Code always returns the same id whatever box you check to edit or delete.
here is the updated ActivityAdapter
package com.example.activitytracker;
import android.content.Context;
import android.database.Cursor;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CursorAdapter;
import android.widget.TextView;
public class ActivityAdapter extends CursorAdapter {
private final SparseBooleanArray checked = new SparseBooleanArray();
public ActivityAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.activity, parent, false);
}
#Override
public void bindView(View view, Context context, final Cursor cursor) {
// Find fields to populate in inflated template
TextView activityTitle = (TextView) view.findViewById(R.id.activityTitle);
TextView activityDescription = (TextView) view.findViewById(R.id.activityDescription);
TextView activityDate = (TextView) view.findViewById(R.id.activityDate);
CheckBox check = (CheckBox) view.findViewById(R.id.checkBox);
check.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
checked.put(cursor.getPosition(), isChecked);
}
});
// Extract properties from cursor
String activity = cursor.getString(cursor.getColumnIndexOrThrow("activity"));
String description = cursor.getString(cursor.getColumnIndexOrThrow("description"));
String date = cursor.getString(cursor.getColumnIndexOrThrow("date"));
// Shorten description for cleaner screen display
String displayValueOfDescription = description;
if (description.length() > 20) {
displayValueOfDescription = description.substring(0, 19) + "...";
}
// Create UK date format for screen display
String yearDB = date.substring(0, 4);
String monthDB = date.substring(5, 7);
String dayDB = date.substring(8, 10);
String dateDB = dayDB + "-" + monthDB + "-" + yearDB;
// Populate fields with extracted properties
activityTitle.setText(activity);
activityDescription.setText(String.valueOf(displayValueOfDescription));
activityDate.setText(String.valueOf(dateDB));
}
public boolean isChecked(int pos) {
return checked.get(pos, false);
}
public void update(Cursor cursor) {
this.swapCursor(cursor);
this.notifyDataSetChanged();
}
}
and my call to the isChecked method in MainActivity
public void editActivity(View view) {
editIds.clear();
//Check to see if any activities are ticked (checked) and grab the id if they are.
// Add checked items to deleteIds
for (int i = 0; i < adapter.getCount(); i++) {
if (adapter.isChecked(i)) {
editIds.add(adapter.getItemId(i));
Log.d("EDITACT", "ID="+adapter.getItemId(i) + "size="+editIds.size());
}
}
//If only one item is checked start the Edit activity
if (editIds.size() == 1) {
Intent intent = new Intent(this, EditActivity.class);
intent.putExtra("ID", String.valueOf(editIds.get(0)));
startActivityForResult(intent, 2);
}
//If more than 1 or none are checked inform the user
else {
String output = "VIEW / EDIT: Please select one activity.";
Toast.makeText(this, output, Toast.LENGTH_SHORT).show();
}
}
Further update
My ActivityAdapter now looks like this.
package com.example.activitytracker;
import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import java.util.ArrayList;
import java.util.List;
class Activities {
private boolean checked = false;
private DBManager dbManager;
Cursor cursor = dbManager.fetch();
public Activities(Cursor cursor) {
List<Activities> items = new ArrayList<>();
while (cursor.moveToNext()){
items.add(new Activities(cursor));
}
}
}
public class ActivityAdapter extends BaseAdapter {
private final List<Activities> items;
private final LayoutInflater inflater;
public ActivityAdapter(Context context, List<Activities> items) {
this.items = items;
this.inflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.activity, parent, false);
}
final Activities item = items.get(position);
CheckBox checkBox = convertView.findViewById(R.id.checkBox);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// item.isChecked() = isChecked;
}
});
// *** Bind the data to the view ***
return convertView;
}
public boolean isChecked(int pos) {
// return items.get(pos).checked;
return true;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
}
Also now my adapter is not populating my listView on startup and any call to adapter crashes the app.
Here is where I used to check the listview for checked boxes then refresh the adaptor. Not sure what to do here now.
deleteIds.clear();
// Add checked items to deleteIds
for (int i = 0; i < adapter.getCount(); i++) {
CheckBox c = listView.getChildAt(i).findViewById(R.id.checkBox);
if (c.isChecked()) {
deleteIds.add(adapter.getItemId(i));
}
}
//Check to see if any activities are ticked (checked)
if (deleteIds.size() > 0) {
//If there are checked activities a dialog is displayed for user to confirm
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to delete?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
for (int i = 0; i < deleteIds.size(); i++) {
dbManager.delete(deleteIds.get(i));
adapter.update(dbManager.fetch());
}
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
deleteIds.clear();
dialog.cancel();
}
}).show();
}
}
Thanks so much for you help so far.
This is a bit of code I wrote to put all the Cursor data into objects and then bind these objects to views. This way it is much easier to control the checkbox state.
public class CustomItem {
public boolean checked = false;
public CustomItem(Cursor cursor) {
// Get yuor data and put it in the object
}
}
public class CustomAdapter extends BaseAdapter {
private final List<CustomItem> items;
private final LayoutInflater inflater;
public CustomAdapter(Context context, List<CustomItem> items) {
this.items = items;
this.inflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(/* Your layout ID */, parent, false);
}
final CustomItem item = items.get(position);
CheckBox checkBox = convertView.findViewById(R.id.checkBox);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
item.checked = isChecked;
}
});
// *** Bind the data to the view ***
return convertView;
}
public boolean isChecked(int pos) {
return items.get(pos).checked;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
}
Cursor cursor = ....;
List<CustomItem> items = new ArrayList<>();
while (cursor.moveToNext())
items.add(new CustomItem(cursor));
Adapter adapter = new BaseAdapter(this /* Your activity */, items);
listView.setAdapter(adapter);
for (int i = 0; i < adapter.getCount(); i++) {
System.out.println(i + " IS " + adapter.isChecked(i));
}
I have created a list view with multiple items in row. I have also created a search box above. I want to implement search functionality on the basis of particular fields of the list. How can I achieve this? Any help will be appreciated.
You have to use model, listview, and customadapter with filtering for this.
I have created a demo for this.
Suppose you have a model named Product, and you are displaying its content in a custom listview where name and price are displayed in a textview. I mean in a custom row having two textviews, and you want to filter the list by one of the field of custom row. Here I have filtered with "name"
Screenshots:
Initial
Filtered
Source code
Model
public class Product {
public String name;
public Integer price;
public Product(String name, Integer price) {
super();
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
}
Activity with custom adapter and listview
public class MainActivity extends Activity {
private LinearLayout llContainer;
private EditText etSearch;
private ListView lvProducts;
private ArrayList<Product> mProductArrayList = new ArrayList<Product>();
private MyAdapter adapter1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialize();
// Add Text Change Listener to EditText
etSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Call back the Adapter with current character to Filter
adapter1.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
private void initialize() {
etSearch = (EditText) findViewById(R.id.etSearch);
lvProducts = (ListView)findViewById(R.id.lvOS);
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
mProductArrayList.add(new Product("a", 100));
mProductArrayList.add(new Product("b", 200));
mProductArrayList.add(new Product("c", 300));
mProductArrayList.add(new Product("d", 400));
mProductArrayList.add(new Product("e", 500));
mProductArrayList.add(new Product("f", 600));
mProductArrayList.add(new Product("g", 700));
mProductArrayList.add(new Product("h", 800));
mProductArrayList.add(new Product("i", 900));
mProductArrayList.add(new Product("j", 1000));
mProductArrayList.add(new Product("k", 1100));
mProductArrayList.add(new Product("l", 1200));
mProductArrayList.add(new Product("m", 1000));
mProductArrayList.add(new Product("n", 1300));
mProductArrayList.add(new Product("o", 1400));
mProductArrayList.add(new Product("p", 1500));
adapter1 = new MyAdapter(MainActivity.this, mProductArrayList);
lvProducts.setAdapter(adapter1);
}
// Adapter Class
public class MyAdapter extends BaseAdapter implements Filterable {
private ArrayList<Product> mOriginalValues; // Original Values
private ArrayList<Product> mDisplayedValues; // Values to be displayed
LayoutInflater inflater;
public MyAdapter(Context context, ArrayList<Product> mProductArrayList) {
this.mOriginalValues = mProductArrayList;
this.mDisplayedValues = mProductArrayList;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return mDisplayedValues.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
LinearLayout llContainer;
TextView tvName,tvPrice;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.row, null);
holder.llContainer = (LinearLayout)convertView.findViewById(R.id.llContainer);
holder.tvName = (TextView) convertView.findViewById(R.id.tvName);
holder.tvPrice = (TextView) convertView.findViewById(R.id.tvPrice);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvName.setText(mDisplayedValues.get(position).name);
holder.tvPrice.setText(mDisplayedValues.get(position).price+"");
holder.llContainer.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(MainActivity.this, mDisplayedValues.get(position).name, Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,FilterResults results) {
mDisplayedValues = (ArrayList<Product>) results.values; // has the filtered values
notifyDataSetChanged(); // notifies the data with new filtered values
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults(); // Holds the results of a filtering operation in values
ArrayList<Product> FilteredArrList = new ArrayList<Product>();
if (mOriginalValues == null) {
mOriginalValues = new ArrayList<Product>(mDisplayedValues); // saves the original data in mOriginalValues
}
/********
*
* If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values
* else does the Filtering and returns FilteredArrList(Filtered)
*
********/
if (constraint == null || constraint.length() == 0) {
// set the Original result to return
results.count = mOriginalValues.size();
results.values = mOriginalValues;
} else {
constraint = constraint.toString().toLowerCase();
for (int i = 0; i < mOriginalValues.size(); i++) {
String data = mOriginalValues.get(i).name;
if (data.toLowerCase().startsWith(constraint.toString())) {
FilteredArrList.add(new Product(mOriginalValues.get(i).name,mOriginalValues.get(i).price));
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
return filter;
}
}
}
activity_main.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="fill_parent"
android:orientation="vertical" >
<EditText
android:id="#+id/etSearch"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<ListView
android:id="#+id/lvProducts"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
></ListView>
</LinearLayout>
row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:id="#+id/tvName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_weight="1"
/>
<TextView
android:id="#+id/tvPrice"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_weight="1"
/>
</LinearLayout>
Implement filterable in your customadapter class.
public class MainActivity extends AppCompatActivity {
String names[] = {"Apple","Banana","Kiwi","Oranges","Watermelon"};
String emails[] = {"This is apple","This is banana","This is kiwi","This is oranges","This is watermelon"};
int images[] = {R.drawable.apple,R.drawable.banana,R.drawable.kiwi,R.drawable.oranges,R.drawable.watermelon};
List<ItemsModel> itemsModelList = new ArrayList<>();
ListView listView;
CustomAdapter customAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listview);
for(int i = 0;i < names.length;i++){
ItemsModel itemsModel = new ItemsModel(names[i],emails[i],images[i]);
itemsModelList.add(itemsModel);
}
customAdapter = new CustomAdapter(itemsModelList,this);
listView.setAdapter(customAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search_menu,menu);
MenuItem menuItem = menu.findItem(R.id.searchView);
SearchView searchView = (SearchView) menuItem.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
Log.e("Main"," data search"+newText);
customAdapter.getFilter().filter(newText);
return true;
}
});
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if(id == R.id.searchView){
return true;
}
return super.onOptionsItemSelected(item);
}
public class CustomAdapter extends BaseAdapter implements Filterable {
private List<ItemsModel> itemsModelsl;
private List<ItemsModel> itemsModelListFiltered;
private Context context;
public CustomAdapter(List<ItemsModel> itemsModelsl, Context context) {
this.itemsModelsl = itemsModelsl;
this.itemsModelListFiltered = itemsModelsl;
this.context = context;
}
#Override
public int getCount() {
return itemsModelListFiltered.size();
}
#Override
public Object getItem(int position) {
return itemsModelListFiltered.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = getLayoutInflater().inflate(R.layout.row_items,null);
TextView names = view.findViewById(R.id.name);
TextView emails = view.findViewById(R.id.email);
ImageView imageView = view.findViewById(R.id.images);
names.setText(itemsModelListFiltered.get(position).getName());
emails.setText(itemsModelListFiltered.get(position).getEmail());
imageView.setImageResource(itemsModelListFiltered.get(position).getImages());
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("main activity","item clicked");
startActivity(new Intent(MainActivity.this,ItemsPreviewActivity.class).putExtra("items",itemsModelListFiltered.get(position)));
}
});
return view;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if(constraint == null || constraint.length() == 0){
filterResults.count = itemsModelsl.size();
filterResults.values = itemsModelsl;
}else{
List<ItemsModel> resultsModel = new ArrayList<>();
String searchStr = constraint.toString().toLowerCase();
for(ItemsModel itemsModel:itemsModelsl){
if(itemsModel.getName().contains(searchStr) || itemsModel.getEmail().contains(searchStr)){
resultsModel.add(itemsModel);
}
filterResults.count = resultsModel.size();
filterResults.values = resultsModel;
}
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
itemsModelListFiltered = (List<ItemsModel>) results.values;
notifyDataSetChanged();
}
};
return filter;
}
}
}
full tutorial can be found here:
listview with search and onItemClickListner
for this, you first need to add an edittext, where you will type to filter data from the list,
then enable filteration in the list,
editText = (EditText) findViewById(R.id.searchList);
adapter = new CustomListViewAdapter(this,
R.layout.list_row, rowItems);
listView.setAdapter(adapter);
listView.setTextFilterEnabled(true);
Then you need to add TextChangeListener() for the edittext,
editText.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
}
public void afterTextChanged(Editable arg0) {
MyActivityName.this.adapter.getFilter().filter(arg0);
}
});
You can set a TextWatcher for your search box and change your Cursor on onTextChanged() on TextWatcher like Codes below :
TextWatcher filterNameTextWatcher = new TextWatcher()
public void beforeTextChanged(CharSequence s, int start, int count,int after)
{
}
public void onTextChanged(CharSequence s,int start, int before,int count)
{
Cursor FilteredNameList = ZoneCardDBAdapter.instance.CursorFilteredName(s.toString());
Listadapter.changeCursor(FilteredNameList);
}
#Override
public void afterTextChanged(Editable arg0)
{
}
};
EditText filterTextName = (EditText)this.findViewById(R.id.edtZoneCardNameFilter);
filterTextCPName.addTextChangedListener(filterNameTextWatcher);
Use below kind of method.
your edit text box.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable theWatchedText) {
}
});
}
SearchWithMenuActivity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".SearchWithMenuActivity">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="#layout/expand_layout"
android:id="#+id/recycler_view"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="vertical"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
search_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/app_bar_search"
android:icon="#drawable/ic_search_black_24dp"
android:title="#string/search"
app:showAsAction="ifRoom|withText"
app:actionViewClass="androidx.appcompat.widget.SearchView"/>
</menu>
expand_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:background="?attr/selectableItemBackground"
android:elevation="6dp">
<androidx.cardview.widget.CardView
android:id="#+id/cardview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
app:cardCornerRadius="5dp"
app:cardUseCompatPadding="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/layout_click"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/srNo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="#string/srNo"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="#+id/part_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="8dp"
android:text="#string/enter_the_name"
android:textSize="16sp"
android:textStyle="bold" />
<ImageView
android:id="#+id/arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="#string/todo"
android:padding="8dp"
android:src="#drawable/arrow_down_24" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
ExpandModel.kt
package com.materialsouk.allcodeapp.models
class ExpandModel(private var name:String,private var expanded:Boolean = false) {
fun setName(name: String) {
this.name = name
}
fun getName():String{
return name
}
fun setExpanded(expanded: Boolean) {
this.expanded = expanded
}
fun getExpanded():Boolean{
return expanded
}
}
ExpandAdapter.kt
package com.materialsouk.allcodeapp.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.materialsouk.allcodeapp.R
import java.util.ArrayList
import android.view.animation.Animation.RELATIVE_TO_SELF
import android.view.animation.RotateAnimation
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import com.materialsouk.allcodeapp.models.ExpandModel
class ExpandAdapter(private var expandList: ArrayList<ExpandModel>) :
RecyclerView.Adapter<ExpandAdapter.ViewHolder>() {
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
val srNo: TextView = itemView.findViewById(R.id.srNo)
val nameTxt: TextView = itemView.findViewById(R.id.part_name)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view: View =
LayoutInflater.from(parent.context).inflate(R.layout.expand_layout, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.srNo.text = (position + 1).toString()
holder.nameTxt.text = expandList[position].getName()
}
override fun getItemCount(): Int {
return expandList.size
}
}
SearchWithMenuActivity.kt
package com.materialsouk.allcodeapp
import android.annotation.SuppressLint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import androidx.appcompat.widget.SearchView
import androidx.recyclerview.widget.RecyclerView
import com.materialsouk.allcodeapp.adapters.ExpandAdapter
import com.materialsouk.allcodeapp.models.ExpandModel
import java.util.*
import kotlin.collections.ArrayList
class SearchWithMenuActivity : AppCompatActivity() {
private lateinit var arrayList: ArrayList<ExpandModel>
private lateinit var adapter: ExpandAdapter
private lateinit var recyclerView: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search_with_menu)
recyclerView = findViewById(R.id.recycler_view)
arrayList = ArrayList()
arrayList.add(ExpandModel("Meet", false))
arrayList.add(ExpandModel("Ankit", false))
arrayList.add(ExpandModel("Rushil", false))
arrayList.add(ExpandModel("Abhishek", false))
arrayList.add(ExpandModel("Modi", false))
arrayList.add(ExpandModel("Ghree", false))
arrayList.add(ExpandModel("Kirtan", false))
arrayList.add(ExpandModel("Ankita", false))
arrayList.add(ExpandModel("Soham", false))
arrayList.add(ExpandModel("Ganesh", false))
arrayList.add(ExpandModel("Dixit", false))
arrayList.add(ExpandModel("Ankash", false))
arrayList.add(ExpandModel("Parth", false))
arrayList.add(ExpandModel("Pranav", false))
arrayList.add(ExpandModel("Ankit Sir", false))
arrayList.add(ExpandModel("Priya Mem", false))
arrayList.add(ExpandModel("Jinal Mem", false))
arrayList.add(ExpandModel("Bhumi", false))
arrayList.add(ExpandModel("Nidhi", false))
arrayList.add(ExpandModel("Hardik", false))
arrayList.add(ExpandModel("Mayank", false))
arrayList.add(ExpandModel("Kaushik", false))
arrayList.add(ExpandModel("Rinku", false))
arrayList.add(ExpandModel("Mom", false))
adapter = ExpandAdapter(arrayList)
recyclerView.adapter = adapter
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.search_menu, menu)
val search = menu.findItem(R.id.app_bar_search)
val searchView = search.actionView as SearchView
searchView.maxWidth = android.R.attr.width
searchView.queryHint = "Search"
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
#SuppressLint("NotifyDataSetChanged")
override fun onQueryTextChange(newText: String?): Boolean {
val freeServiceModelArrayList: ArrayList<ExpandModel> = ArrayList()
for (i in arrayList) {
if (i.getName().lowercase(Locale.getDefault()).contains(
newText!!.lowercase(
Locale.getDefault()
)
)
) {
freeServiceModelArrayList.add(i)
}
}
adapter = ExpandAdapter(freeServiceModelArrayList)
recyclerView.adapter = adapter
adapter.notifyDataSetChanged()
return true
}
})
return super.onCreateOptionsMenu(menu)
}
}
I'm trying to get the onclick event of a button inside a listview, but it's not working
fragment_contact.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="404dp"
android:layout_weight="0.64"
android:orientation="horizontal"
android:paddingBottom="40dip" >
<ListView
android:id="#+id/contactlistview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="fill"
android:layout_weight="10"
android:textSize="5pt"
android:visibility="visible" />
</LinearLayout>
fragment_contact_content.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="fill_parent"
android:orientation="vertical"
android:weightSum="1">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/btn_edit_contact"
android:layout_gravity="right" />
</LinearLayout>
FragmentContact.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_contact, container, false);
ListAdapter adapter_contact = new SimpleAdapter(
getActivity(), allcontact,
R.layout.fragment_contact_content, new String[]{"name", "level", "function", "phone", "email"},
new int[]{R.id.contact, R.id.level, R.id.function, R.id.phone, R.id.email});
listview_contact = (ListView) view.findViewById(R.id.contactlistview);
listview_contact.setItemsCanFocus(true);
listview_contact.setAdapter(adapter_contact);
Button btn_edit_contact = (Button) view.findViewById(R.id.btn_edit_contact);
btn_edit_contact.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("Do something");
}
});
return view;
}
I also tried inflating fragment_contact_content.xml but the button still does nothing.
Use custom Adapter and in getView Write your code
public class MealAdapter extends BaseAdapter{
private int mHour, mMinute;
int minutes,hour;
String strtime;
customButtonListener customListner;
private Context context;
private List<Meal> rowItems;
public MealAdapter(Context context, List<Meal> rowItems) {
this.context = context;
this.rowItems = rowItems;
}
#Override
public int getCount() {
return rowItems.size();
}
#Override
public Object getItem(int position) {
return rowItems.get(position);
}
#Override
public long getItemId(int position) {
return rowItems.indexOf(getItem(position));
}
private class OptionHolder
{
ImageButton btn_time;
ImageButton btn_delete;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
// TODO Auto-generated method stub
final OptionHolder holder;
if (convertView == null)
{
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.meal_list_item, null);
holder = new OptionHolder();
holder.btn_time= (ImageButton) convertView.findViewById(R.id.btn_time);
holder.btn_delete =(ImageButton) convertView.findViewById(R.id.btn_delete_meal);
convertView.setTag(holder);
}
else
{
holder = (OptionHolder) convertView.getTag();
}
final Meal row_pos=rowItems.get(position);
row_pos.setMeal("");
row_pos.setDetail("");
holder.ed_meal.setText(row_pos.getMeal());
holder.ed_detail.setText(row_pos.getDetail());
holder.ed_time.setText(row_pos.getTime());
holder.btn_time.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
final Calendar c = Calendar.getInstance();
mHour = c.get(Calendar.HOUR_OF_DAY);
mMinute = c.get(Calendar.MINUTE);
// Launch Time Picker Dialog
TimePickerDialog tpd = new TimePickerDialog(MealPlannerFragment.con,
new TimePickerDialog.OnTimeSetListener() {
#Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
// Display Selected time in textbox
strtime=(hourOfDay + ":" + minute);
row_pos.setTime(strtime);
row_pos.setMunite(minute);
row_pos.setHour(hourOfDay);
holder.ed_time.setText(row_pos.getTime());
}
}, mHour, mMinute, false);
tpd.show();
}
});
holder.btn_delete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if (customListner != null) {
customListner.onButtonClickListner(position,row_pos);
}
}
});
return convertView;
}
public interface customButtonListener {
public void onButtonClickListner(int position,Meal row_pos);
}
public void setCustomButtonListner(customButtonListener listener) {
this.customListner = listener;
}
}
`
you can not get Listview cell's Button event directly in onCreateView. you have to make CustomAdapter class for that.
you will need to create a Custom ArrayAdapter Class which you will use to inflate your xml layout, as well as handle your buttons and on click events.
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.fragment_contact_content, null);
}
//Handle button and add onClickListener
Button editBtn = (Button)view.findViewById(R.id.btn_edit_contact);
editBtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
//do something
//some other task
notifyDataSetChanged();
}
});
return view;
}
}
Finally, in your activity you can instantiate your custom ArrayAdapter class and set it to your listview
public class MyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_activity);
//generate list
ArrayList<String> list = new ArrayList<String>();
list.add("item1");
list.add("item2");
//instantiate custom adapter
MyCustomAdapter adapter = new MyCustomAdapter(list, this);
//handle listview and assign adapter
ListView lView = (ListView)findViewById(R.id.my_listview);
lView.setAdapter(adapter);
}
You can refer this link: http://www.c-sharpcorner.com/UploadFile/9e8439/create-custom-listener-on-button-in-listitem-listview-in-a/
just handle on click listener inside getview where you find the button using findviewbyid
I hope it helps!
So, here is the thing. I wanted to experiment a bit. So, i wrote this program which looks for images with (.jpg) extension in my mnt/shared/Newpictures folder in my GennyMotion Emulator. In my program, i captured the name of the files with .jpg extension in a String array adapter and the file path in a filepath string array. Now, here is the part where i am blank, i have the path,name and i can get the position by clicking on the list. But how do i open the image when i click on the list. I researched online and most of the codes were too confusing. So, may be someone can suggest me an easier approach. This is what i tried so far. Thanks.
package com.example.user.imageapp;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import java.io.File;
import java.util.ArrayList;
/**
* Created by user on 06-08-2015.
*/
public class Splash extends Activity {
Button load;
String s;
private ListView mainList;
private String[] FilePathStrings;
ArrayList<String>filesinFolder = GetFiles("/mnt/shared/NewPictures");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
// load = (Button)findViewById(R.id.Load);
mainList = (ListView) findViewById(R.id.imagelist);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,filesinFolder );
mainList.setAdapter(adapter);
mainList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//what do i put here
}
});
}
public ArrayList<String> GetFiles(String DirectoryPath)
{
ArrayList<String> MyFiles = new ArrayList<String>();
File f = new File(DirectoryPath);
f.mkdirs();
File[] files = f.listFiles();
FilePathStrings = new String[files.length];
for (int i = 0; i < files.length; i++) {
// Get the path of the image file
if(files[i].getName().contains(".jpg")) {
FilePathStrings[i] = files[i].getAbsolutePath();
// Get the name image file
MyFiles.add(files[i].getName());
}
}
return MyFiles;
}
}
A simple way to achieve this would be to create a dialog containing an imageview and then set the imageview's image to the file. Something like this should do the job:
public void onItemclick(AdapterView<?> adapterView, View view, int pos, long id){
String filePath = filesInFolder.get(pos);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_img_preview, null);
builder.setView(view);
ImageView imgView = (ImageView)view.findViewById(R.id.preview_imgview);
imgView.setImageBitmap(BitmapFactory.decodeFile(filePath));
AlertDialog dialog = builder.create();
dialog.show();
}
Here is simple example, how you can view image by click on gridview but you can change to listview in xml file.
This is gridview display.
GridViewActivity.java
public class GridViewActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gridview);
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(GridViewActivity.this));
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// Send intent to SingleViewActivity
Intent i = new Intent(getApplicationContext(), SingleViewActivity.class);
// Pass image index
i.putExtra("id", position);
startActivity(i);
}
});
}
}
This class will display image in single page.
SingleViewActivity.java
public class SingleViewActivity extends Activity {
ImageLoader imageLoader = ImageLoader.getInstance();
private DisplayImageOptions options;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.single_view);
options = new DisplayImageOptions.Builder().cacheInMemory(true)
.cacheOnDisk(true).considerExifParams(true)
.showImageForEmptyUri(R.mipmap.ic_launcher)
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
.bitmapConfig(Bitmap.Config.RGB_565).build();
// Get intent data
Intent i = getIntent();
// Selected image id
int position = i.getExtras().getInt("id");
ImageAdapter imageAdapter = new ImageAdapter(this);
ImageView imageView = (ImageView) findViewById(R.id.SingleView);
//imageView.setImageResource(imageAdapter.mThumbnames[position]);
imageLoader.displayImage(imageAdapter.mThumbnames[position],imageView,options);
}
}
i have used some random images from internet. This same concept is used in listview for displaying image.
ImageAdapter.java
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater layoutInflater;
ImageLoader imageLoader = ImageLoader.getInstance();
private DisplayImageOptions options;
// Constructor
public ImageAdapter(Context c) {
mContext = c;
layoutInflater = LayoutInflater.from(mContext);
options = new DisplayImageOptions.Builder().cacheInMemory(true)
.cacheOnDisk(true).considerExifParams(true)
.showImageForEmptyUri(R.mipmap.ic_launcher)
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
.bitmapConfig(Bitmap.Config.RGB_565).build();
}
public int getCount() {
return mThumbnames.length;
}
public Integer getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder1 holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.grideview_item, null);
holder = new ViewHolder1();
holder.image = (ImageView) convertView.findViewById(R.id.imageView);
convertView.setTag(holder);
} else {
holder = (ViewHolder1) convertView.getTag();
}
// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view
// which implements ImageAware interface)
//imageLoader.displayImage("drawable://" + mThumbIds[position], holder.image);
imageLoader.displayImage(mThumbnames[position], holder.image, options);
//holder.image.setImageDrawable(mContext.getResources().getDrawable(mThumbIds[position]));
return convertView;
}
public static class ViewHolder1 {
ImageView image;
}
// Keep all Images in array
/* public Integer[] mThumbIds = {
R.drawable.ab, R.drawable.ac,
R.drawable.ad, R.drawable.ae
};*/
public String[] mThumbnames = {
"http://cdn2.ubergizmo.com/wp-content/uploads/2012/05/android_lock.jpg",
"http://cdn2.ubergizmo.com/wp-content/uploads/2012/05/android_lock.jpg",
"http://cdn2.ubergizmo.com/wp-content/uploads/2012/05/android_lock.jpg",
"http://cdn2.ubergizmo.com/wp-content/uploads/2012/05/android_lock.jpg",
"http://cdn2.ubergizmo.com/wp-content/uploads/2012/05/android_lock.jpg",
"http://cdn2.ubergizmo.com/wp-content/uploads/2012/05/android_lock.jpg",
"http://cdn2.ubergizmo.com/wp-content/uploads/2012/05/android_lock.jpg",
"http://cdn2.ubergizmo.com/wp-content/uploads/2012/05/android_lock.jpg"
};
}
gridview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="10dp"
android:scaleType="fitXY" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_gravity="center|bottom"
android:layout_marginBottom="5dip"
android:background="#80000000"
android:gravity="center"
android:text="images"
android:textColor="#000000"
android:textSize="20dp" />
</FrameLayout>
I have a problem with the GridView.
I would like to have a Grid with pictures and under each of them should be a timer. When I click one of the images, there should start the timer bellow of it.
How can I adapt TextViews and Images to a Gridview and let the TextView change every second.
I changed my code now to this
MainActivity
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends Activity implements Runnable{
/** The Constant INTERVALL. */
private static final int INTERVALL = 1000;
private ImageAdapter mAdapter;
private ArrayList<String> listText;
private ArrayList<Integer> listImage;
private GridView gridView;
/** The handler. */
private Handler handler = new Handler();
public boolean timerRuns = false;
public int time ;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grid);
//GridView gridview = (GridView) findViewById(R.id.gridview);
//gridview.setAdapter(new ImageAdapter(this));
prepareList();
// prepared arraylist and passed it to the Adapter class
mAdapter = new ImageAdapter(this, listText, listImage);
// Set custom adapter to gridview
gridView = (GridView) findViewById(R.id.gridView);
gridView.setAdapter(mAdapter);
// Implement On Item click listener
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
Toast.makeText(MainActivity.this, mAdapter.getItem(position), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public final void run() {
chronometer();
}
public void startTimer(View v) {
timerRuns = true;
time = 5*60;
update();
this.handler.postDelayed(this, INTERVALL);
}
public void stopTimer(View v) {
timerRuns = false;
handler.removeCallbacks(this);
}
public void chronometer(){
time = time -1;
update();
handler.postDelayed(this, INTERVALL);
}
private void update(){
updateScreen();
}
private void updateScreen(){
//TextView tvChronometer = (TextView)findViewById(R.id.tvChronometer);
//tvChronometer.setText(Integer.toString(time));
}
public void prepareList()
{
listText = new ArrayList<String>();
listText.add("Sample");
listText.add("Brazil");
listText.add("Canada");
listText.add("China");
listText.add("France");
listText.add("Germany");
listText.add("Iran");
listText.add("Italy");
listText.add("Japan");
listText.add("Korea");
listText.add("Mexico");
listText.add("Netherlands");
listText.add("Portugal");
listText.add("Russia");
listText.add("Saudi Arabia");
listText.add("Spain");
listText.add("Turkey");
listText.add("United Kingdom");
listText.add("United States");
listImage = new ArrayList<Integer>();
listImage.add(R.drawable.sample_0);
listImage.add(R.drawable.sample_3);
listImage.add(R.drawable.sample_3);
listImage.add(R.drawable.sample_7);
listImage.add(R.drawable.sample_1);
listImage.add(R.drawable.sample_6);
listImage.add(R.drawable.sample_2);
listImage.add(R.drawable.sample_7);
listImage.add(R.drawable.sample_4);
listImage.add(R.drawable.sample_5);
listImage.add(R.drawable.sample_0);
listImage.add(R.drawable.sample_5);
listImage.add(R.drawable.sample_0);
listImage.add(R.drawable.sample_2);
listImage.add(R.drawable.sample_1);
listImage.add(R.drawable.sample_4);
listImage.add(R.drawable.sample_3);
listImage.add(R.drawable.sample_1);
listImage.add(R.drawable.sample_6);
}
}
The ImageAdapter
`public class ImageAdapter extends BaseAdapter {
private ArrayList<String> listText;
private ArrayList<Integer> listImage;
private Activity activity;
public ImageAdapter(Activity activity,ArrayList<String> listText, ArrayList<Integer> listImage) {
super();
this.listText = listText;
this.listImage = listImage;
this.activity = activity;
}
#Override
public int getCount() {
return listText.size();
}
#Override
public String getItem(int position) {
return listText.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
public static class ViewHolder
{
public ImageView imgView;
public TextView txtView;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder view;
LayoutInflater inflator = activity.getLayoutInflater();
if(convertView==null)
{
view = new ViewHolder();
convertView = inflator.inflate(R.layout.element, null);
view.txtView = (TextView) convertView.findViewById(R.id.eText);
view.imgView = (ImageView) convertView.findViewById(R.id.eImage);
convertView.setTag(view);
}
else
{
view = (ViewHolder) convertView.getTag();
}
view.txtView.setText(listText.get(position));
view.imgView.setImageResource(listImage.get(position));
return convertView;
}
}`
my gridview
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="110dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
and my element.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp" >
<ImageView
android:id="#+id/eImage"
android:layout_width="120dp"
android:layout_height="120dp"
android:src="#color/Bisque" >
</ImageView>
<TextView
android:id="#+id/eText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="15sp" >
</TextView>
I hope you can help me.
1. Creating a gridview with text and image in each cell
Take a look at the documentation for GridView:
http://developer.android.com/guide/topics/ui/layout/gridview.html
The key method there is the public View getView(int position, View convertView, ViewGroup parent)
That method returns a view for each cell in the grid. You can create an XML layout that includes the TextView and ImageView. In the getView method for the adapter inflate the XML layout, attach an onClickListener so you can start the timer and return it as a view.
2. Updating the TextView from the grid
Keep in mind that a gridview contains contains multiple views, each of which can come from the same resource so this: TextView tvChronometer = (TextView)findViewById(R.id.tvChronometer); is not going to work in a gridview.
What you need to do is to get the specific view from the cell that you need (or iterate through all of them) and update the view. Something like this:
//First get the view for the cell assuming it's a composite view
View cellView = (TextView) gridview.getChildAt(position);
//Then get the actual TextView from that grid cell
TextView tvChronometer = cellView.findViewById(R.id.tvChronometer);
Although the best way in my opinion is to save a reference to the TextView when you a creating/instantiating it in the adapter.