Reputation: 251
I can populate my list with the database values. My problem is that ListView layout looks like this (for example) -> ( textview, delete button )
Activity 1 || Delete_Button
Activity 2 || Delete_Button
and what i want is that when i clicked Activity 1, it will go to Activity 1 intent. or when i clicked Activity 2, it will go to Activity 2 intent. same as the delete button, if I clicked the row 1 delete button, it will delete row 1 and etc.
How to do this ? I'm new at Android.
This is my code:
ListView listView ;
ArrayList<String> list;
public int goal_id;
int i = 0;
//database variables
MyDBAdapter dbhandler;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_act);
TypefaceProvider.registerDefaultIconSets();
Bundle extras = getIntent().getExtras();
if (extras == null) {
return;
}
goal_id = Integer.parseInt(extras.getString("goalid"));
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setSubtitle("Activities List");
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeAsUpIndicator(R.drawable.ic_back);
actionBar.setDisplayHomeAsUpEnabled(true);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Added new activity", Snackbar.LENGTH_LONG)
.setAction("Added new activity", null).show();
onCLick_addAct();
}
});
dbhandler = new MyDBAdapter(this);
populateListView();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Long temp = listView.getItemIdAtPosition(position);
MessageTo.message(SetActActivity.this, Long.toString(temp));
}
});
}
public void populateListView(){
Cursor cursor = dbhandler.getAllActivitiesByGoalCursor(goal_id);
String[] actlist = new String[] {dbhandler.dbhandler.COLUMN_ACTIVITY_NAME};
int[] actNames = new int[] {R.id.list_item_string};
SimpleCursorAdapter myAdapter = new SimpleCursorAdapter(SetActActivity.this,R.layout.act_list,cursor,actlist,actNames,0){
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if (v == null) {
holder = new ViewHolder();
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.act_list, null);
holder.textView = (TextView) v.findViewById(R.id.list_item_string);
holder.button = (Button) v.findViewById(R.id.delete_btn);
v.setTag(holder);
holder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = (int) v.getTag();
list.remove(pos);
notifyDataSetChanged();
}
});
} else {
holder = (ViewHolder) v.getTag();
}
// holder.textView.setText(list.get(position).get("title")); //the get("title") is error. undefined
holder.button.setTag(position);
return v;
}
class ViewHolder {
TextView textView;
Button button;
}
};
//handle listview and assign adapter
listView = (ListView)findViewById(R.id.list);
// Attach cursor adapter to the ListView
listView.setAdapter(myAdapter);
}
This one code -> it wont distinguish if i clicked the textview or the delete button. It will still implement the same function which is not what i want to happen. :(
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Long temp = listView.getItemIdAtPosition(position);
MessageTo.message(SetActActivity.this, Long.toString(temp));
}
});
Upvotes: 2
Views: 1456
Reputation: 9009
UPDATED : As you can't delete a row/item from cursor and also re-query Cursor every time user presses delete not a good idea.
Instead you can read all values from cursor and put it in List<Map<String,String> items
and pass this object to SimpleAdapter
. try below code.
items = new ArrayList<Map<String,String>>();
Map<String, String> item;
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String name = cursor.getString(cursor.getColumnIndex("title"));//column name
String id = cursor.getString(cursor.getColumnIndex("_id"));//column name
item = new HashMap<>();
item.put("title", name);
item.put("id", id);
items.add(item);
cursor.moveToNext();
}
SimpleAdapter adapter = new SimpleAdapter(this, items, R.layout.adapter_text_button, new String[]{"title"
}, new int[]{R.id.title}) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if (v == null) {
holder = new ViewHolder();
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.adapter_text_button, null);
holder.textView = (TextView) v.findViewById(R.id.title);
holder.button = (Button) v.findViewById(R.id.action);
v.setTag(holder);
holder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = (int) v.getTag();
Map<String, String> item = items.get(pos);
String id = item.get("id");
//using this id delete the record from the database
items.remove(item);
notifyDataSetChanged();
Log.i("TAG", "ID " + id);
}
});
} else {
holder = (ViewHolder) v.getTag();
}
Map<String, String> data = items.get(position);
holder.textView.setText(data.get("title"));
holder.button.setTag(position);
return v;
}
class ViewHolder {
TextView textView;
Button button;
}
};
listView.setAdapter(adapter);
Upvotes: 2
Reputation: 2154
You are using a focusable item (Button
) in a list which is overriding the event of OnItemClickListener
. The solution is to use two separate onClickListeners
while creating the views in the adapter.
This issue is pretty common. See this for reference.
Now, the code for custom SimpleCursorAdapter
:
public class MyAdapter extends SimpleCursorAdapter
{
private Context mContext;
private Context appContext;
private int layout;
private Cursor cr;
private final LayoutInflater inflater;
public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to)
{
super(context, layout, c, from, to);
this.layout = layout;
this.mContext = context;
this.inflater = LayoutInflater.from(context);
this.cr = c;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
return inflater.inflate(layout, null);
}
@Override
public void bindView(View view, final Context context, Cursor cursor)
{
super.bindView(view, context, cursor);
RelativeLayout parentView = (RelativeLayout) view.findViewById(R.id.parentView);
TextView textview = (TextView) view.findViewById(R.id.itemLayoutText);
// Set the text using cursor with column index.
textview.setText(cursor.getString(1));
Button button = (Button) view.findViewById(R.id.itemLayoutBtn);
button.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
// Use interface to send a callback to the activity
Toast.makeText(context, "Button clicked", Toast.LENGTH_SHORT).show();
}
});
parentView.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
// Use interface to send a callback to the activity
Toast.makeText(context, "List item clicked", Toast.LENGTH_SHORT).show();
}
});
}
}
Layout of list item:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/parentView">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:textAppearance="?android:textAppearanceMedium"
android:id="@+id/itemLayoutText"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/itemLayoutBtn"
android:text="Delete"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
Upvotes: 1
Reputation: 3843
You can simply add in your custom adapter's getView() method a setOnClickListener() for the buttons you're using.
Any data associated with the button has to be added with myButton.setTag() in the getView() and can be accessed in the onClickListener via view.getTag()
Check the solution in this link
Upvotes: 0