Scenario:
User clicks a button and a row(adapter) is added. The user inputs a value and clicks on a button which is generated. The value would be computed and displayed in an edit text.
Problem: The value is not computed nor is it being displayed in the edit text. What am I doing wrong?
custom_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center">
<EditText
android:id="#+id/name"
android:layout_width="125dp"
android:layout_height="wrap_content"
android:hint="Name"
android:maxLength="10"
/>
<EditText
android:id="#+id/price"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:hint="Price"
android:inputType="numberDecimal"
android:maxLength="5"
/>
<Button
android:id="#+id/calculate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Calculate"
/>
</LinearLayout>
<EditText
android:id="#+id/result"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:editable="false"
android:cursorVisible="false"
android:text="$0.00"
/>
main.java <<EDITTED>>
public class AdvancedBillSplitter extends Activity{
ArrayList<String> noteList = new ArrayList<String>();
FancyAdapter aa = null;
Button calculate;
//EditText price;
EditText result;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView myListView = (ListView)findViewById(R.id.noteList);
aa = new FancyAdapter();
myListView.setAdapter(aa);
myListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
EditText price = (EditText)findViewById(R.id.price);
price = (EditText)findViewById(R.id.price);
double price1 = Double.parseDouble(price.getText().toString());
double total = price1 *1.1;
String resultPrice = Double.toString(total);
result.setText(resultPrice);
System.out.println(total);
}
});
aa.notifyDataSetChanged();
Button btnSimple = (Button)findViewById(R.id.btnSimple);
btnSimple.setOnClickListener(new OnClickListener() {
public void onClick(View v)
{
noteList.add(0, "");
aa.notifyDataSetChanged();
}
});
}
class FancyAdapter extends ArrayAdapter<String>
{
Button calculate;
EditText price;
EditText result;
FancyAdapter()
{
super(AdvancedBillSplitter.this, android.R.layout.simple_list_item_1, noteList);
}
public View getView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
if(row == null)
{
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.custom_list_item, null);
}
return (row);
}
}
}
simple addition,
<Button
android:id="#+id/calculate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Calculate"
/>
its not catching click event because the list has 2 items which are focussable (The list item and the button) , so now thats an Ambiguous situation. so make the button not focussable. it still catches click events.
Maybe you want to use the recommended method setOnItemClickListener() on the ListView instead - I guess it is a bad style to set the listeners directly within the adapter.
Shouldn't
EditText price = (EditText)findViewById(R.id.price);
be
EditText price = (EditText)view1.findViewById(R.id.price);
(Note the view1)
Also, you have the findViewById() line twice.
You can use the Handler to update your view.
Like this:
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
aa.notifyDataSetChanged();
break;
default:
break;
}
}};
btnSimple.setOnClickListener(new OnClickListener() {
public void onClick(View v)
{
noteList.add(0, "");
mHandler.sendEmptyMessage(0);
}
});
Instead of using new AdapterView.OnItemClickListener(), You can use the new OnItemClickListener() which imports import android.widget.AdapterView.OnItemClickListener;
Dont have the click listener for the inflated layout and also for the parent layout(ie for listview). If you have the inflated layout's click listener then control will directly transfer there.
myListViewmyListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
price = (EditText)findViewById(R.id.price);
double price1 = Double.parseDouble(price.getText().toString());
double total = price1 *1.1;
String resultPrice = Double.toString(total);
result.setText(resultPrice);
}
});
I think this might give you some idea. And once the data has changed try to call the notifyDataSetChanged() method to refresh the view.
All the best.
class FancyAdapter extends BaseAdapter
{
Button calculate;
EditText price;
EditText result;
#Override
public int getCount() {
return noteList.length;
}
#Override
public Object getItem(int arg0) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if(row == null)
{
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.custom_list_item, null);
}
return (row);
}
}
Related
i manage to do when i click the item in my listview , beside the column will show a tick over there, but now i have a problem in when i click on my item the tick will show but there is no function for my onitemclicklistener event. how to let this two function work in same time. sorry for my english, hope can understand
this is my setOnItemClickListener event
condimentlist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView condimentitem =(TextView)view.findViewById(R.id.condcb);
String citem= condimentitem.getText().toString();
ArrayList<String> data = new ArrayList<String>();
data.add(citem);
String array[] = data.toArray(new String[0]);
for (int j = 0; j < array.length; j++) {
remark.append(String.valueOf(array[j]));
}
------condimentitem.setOnClickListener(new View.OnClickListener()-------
{
#Override
public void onClick(View v)
{
int visibility = btntick.getVisibility();
if(visibility == View.VISIBLE)
{
btntick.setVisibility(View.GONE);
}
else
{
btntick.setVisibility(View.VISIBLE);
}
}
});
}
});
this is my baseadapter to contor the tick
public class condimentlist extends BaseAdapter {
LayoutInflater mInflater;
private ArrayList<Integer> positions = new ArrayList<Integer>();
public ArrayList<Integer> getPositions() {
return positions;
}
public condimentlist() {
mInflater = LayoutInflater.from(getActivity());
}
#Override
public int getCount() {
return CondimentList.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.condimentlistview_details, null);
}
condcb = (TextView) convertView.findViewById(R.id.condcb);
final TextView tremark = (TextView) convertView.findViewById(R.id.Tremark);
btntick = (ImageView) convertView.findViewById(R.id.iv_tick);
Condiment myObj = CondimentList.get(position);
condcb.setText("" + myObj.getCondimentName());
-----------convertView.performClick ();------------------
return convertView;
}
condimentlistview_details.xml
<RelativeLayout 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">
<TextView
android:id="#+id/condcb"
android:text="Press"
android:layout_width="150dp"
android:layout_height="30dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:textSize="18sp" />
<ImageButton
android:layout_width="15dp"
android:layout_height="15dp"
android:background="#drawable/tick"
android:id="#+id/iv_tick"
android:visibility="gone"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="150dp"
android:layout_marginStart="150dp" />
</RelativeLayout>
I think problem is ImageButton in your listview Row xml file.
Put android:focusable="false" , and see it works!!!
<ImageButton
android:layout_width="15dp"
android:layout_height="15dp"
android:background="#drawable/tick"
android:id="#+id/iv_tick"
android:visibility="gone"
android:focusable="false"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="150dp"
android:layout_marginStart="150dp" />
Below is one of the question i answered before, you may need to create a list with one of the element of boolean as a flag. When you select, you turn that flag into true. Hope it helps.
enter link description here
You could define a static ArrayList in your activity class, then retrieve everything from that array list in the base adapter with a Hashmap. Then, you could use SetOnItemClickListener in your activity class to get the correct value of each row by referencing the activity's array list's position.
Works for me flawlessly. Let me know if you need example code.
Write this code inside BASE ADAPTER's getView()
condimentitem.setOnClickListener(new View.OnClickListener()-------
{
#Override
public void onClick(View v)
{
int visibility = btntick.getVisibility();
if(visibility == View.VISIBLE)
{
btntick.setVisibility(View.GONE);
}
else
{
btntick.setVisibility(View.VISIBLE);
}
}
});
Add convertView.performClick() inside condcb.OnClick method in adapter.
I am having a problem with a clickListener on my gridview. The LongClickListener works without issue. But I cannot seem to get any response from the click Listener.
My code is below.
Im confused as to why the long click works but not the normal click,
Any pointers would be appreciated
Thanks
final GridView gridView = (GridView) findViewById(R.id.grid_view);
gridView.setNumColumns(numOfColumns);
gridView.getLayoutParams().width = (CELL_WIDTH * numOfColumns);
gridView.getLayoutParams().height = (CELL_WIDTH * numOfRows);
....
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Log.d("ABCD", "Position Single Click is " + position);
// Ideally in here I want to put to open a soft keyboard for the user to enter a value
// InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
// imm.showSoftInput(gridView, InputMethodManager.SHOW_IMPLICIT);
}
});
gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Log.d("ABCD", "Position Long Click is " + position);
return true;
}
});
grid_view is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="horizontal">
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"/>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_grid_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"/> <<--- I WANT THIS TO GET THE CLICK
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"/>
</LinearLayout>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listId"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>
GridCell in the grid view is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:padding="0dp" android:layout_margin="0dp"
android:focusable="false"
android:clickable="false"
android:focusableInTouchMode="false"
>
<TextView
android:id="#+id/grid_item_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="1dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:textSize="10px"
android:focusable="false"
android:clickable="false"
android:focusableInTouchMode="false"
>
</TextView>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid_item_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#+id/celllabel"
android:background="#android:color/transparent"
android:paddingLeft="5dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:layout_margin="0dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"
android:cursorVisible="false">
</EditText>
</RelativeLayout>
The adapter class has a getView and is as below
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
MyObject obj = myObjects.get(position);
if (convertView == null) {
gridView = inflater.inflate(R.layout.grid_cell, null);
String textColour = "#000000";
TextView textView = (TextView) gridView.findViewById(R.id.grid_item_label);
textView.setText(Html.fromHtml(String.format("<font color='%s'>%s</font>", textColour, obj.getValue())));
TextView superScriptTv = (TextView) gridView.findViewById(R.id.grid_item_number);
if (obj.getNumber() > 0) {
superScriptTv.setText(Html.fromHtml(String.format("<font>%s</font>", cell.getNumber())));
}
} else {
gridView = convertView;
}
gridView.setBackgroundColor(obj.getBackgroundColour());
return gridView;
}
EDIT
Really banging my head against a wall here now :)
Im updating the code sample so have more data. Ive noticed that in my adapter if I do not set the text on the textview with ID = R.id.grid_item_number then it works. As soon as I set text on it then I lose the click listener.
The linked question/answer doesnt help from what I can see. Can anyone help with my stupidity?
EDIT
Adapter code has been added.
Thanks in advance.
The problem is with the EditText inside the row_cell. When you click on the item, it takes focus and prevents the whole item to be clickable again. As you noticed, only long click works.
Here you have a similar problem.
To resolve that issue I would move your OnItemClickListeners from the Activity / Fragment to your GridViewAdapter, so instead of:
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Log.d("ABCD", "Position Single Click is " + position);
// Ideally in here I want to put to open a soft keyboard for the user to enter a value
// InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
// imm.showSoftInput(gridView, InputMethodManager.SHOW_IMPLICIT);
}
});
gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Log.d("ABCD", "Position Long Click is " + position);
return true;
}
});
I would do something like that:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridViewItem;
if (convertView == null) {
gridViewItem = new View(mContext);
gridViewItem = layoutInflater.inflate(R.layout.grid_cell, null);
TextView textView = (TextView)gridViewItem.findViewById(R.id.grid_item_number);
textView.setText(mValues[position]);
EditText editText = (EditText)gridViewItem.findViewById(R.id.grid_item_label);
} else {
gridViewItem = (View) convertView;
}
gridViewItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("GRID", "onClick: " );
}
});
gridViewItem.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Log.e("GRID", "onLongClick: " );
return true;
}
});
return gridViewItem;
}
It will prevent this strange behaviour you are struggling right now.
For the sake of that example please find my code below:
MainActivity layout:
<?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:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="io.github.mmbs.gridviewcheck.MainActivity"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp">
<GridView
android:id="#+id/gridView"
android:numColumns="auto_fit"
android:columnWidth="100dp"
android:stretchMode="columnWidth"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true">
</GridView>
</android.support.constraint.ConstraintLayout>
Grid cell layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:padding="8dp">
<TextView
android:id="#+id/grid_item_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="0dp"
android:paddingLeft="1dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:textSize="20sp"
android:text="TEXTVIEW">
</TextView>
<EditText
android:id="#+id/grid_item_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:background="#android:color/transparent"
android:cursorVisible="false"
android:layout_below="#id/grid_item_number"
android:text="EDITTEXT">
</EditText>
</RelativeLayout>
Please take into consideration, that I removed all layouts attributes responsible for focusability.
MyGridAdapter:
public class MyGridViewAdapter extends BaseAdapter {
private Context mContext;
private final String[] mValues;
public MyGridViewAdapter(String[] values, Context context) {
mValues = values;
mContext = context;
}
#Override
public int getCount() {
return mValues.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridViewItem;
if (convertView == null) {
gridViewItem = new View(mContext);
gridViewItem = layoutInflater.inflate(R.layout.grid_cell, null);
TextView textView = (TextView)gridViewItem.findViewById(R.id.grid_item_number);
textView.setText(mValues[position]);
EditText editText = (EditText)gridViewItem.findViewById(R.id.grid_item_label);
} else {
gridViewItem = (View) convertView;
}
gridViewItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("GRID", "onClick: " );
}
});
gridViewItem.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Log.e("GRID", "onLongClick: " );
return true;
}
});
return gridViewItem;
}
}
If you like, I can also share this code on github, so you will have a fully operational example.
The second option is to leave your implementation as it is and do hacks when the EditText is focusable and enabled. Here you have related topics:
Android: Force EditText to remove focus?
ListView items focus behaviour
Focusable EditText inside ListView
Android: Force EditText to remove focus?
What is more, please take into account that answer:
Do not use clickable objects in the grid. In that case Android cannot handle the click event of GridView.
Instead, use something to show a similar user interface view. Then handle that object's click actions.
Don't: put Button in the GridView to perform some click actions.
Do: put an ImageView instead of ImageButton and handle ImageView's click events.
Edit: Please find a link to the project on my Github.
use gridView.setOnItemClickListener(.....) and to your root view add below line
android:descendantFocusability="blocksDescendants"
The ViewGroup will block its descendants from receiving focus.
Try to add
android:focusable="false"
android:focusableInTouchMode="false"
in your GridCell -->TextView
Try using recycler view if you are comfortable with it.
It doesn't gives any such problem in addition to this it has its own advantages.
Follow the link for complete explanation.
If you have any focus-able view in you your row layout, then the onItemClickListener will not be called. For this problem you need to customize your getView code and set onClickListener() on convertView and pass the callback to activity using the Interface. I have updated the code of your Adapter as below. Now you need to implement the GridViewItemClickListener on your activity and pass the instance while creating the Adapter instance.
public class MyGridViewAdapter extends BaseAdapter {
private Context mContext;
private final String[] mValues;
private GridViewItemClickListener mListener;
public MyGridViewAdapter(String[] values, Context context,GridViewItemClickListener listener ) {
mValues = values;
mContext = context;
mListener = listener;
}
#Override
public int getCount() {
return mValues.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridViewItem;
if (convertView == null) {
gridViewItem = new View(mContext);
gridViewItem = layoutInflater.inflate(R.layout.grid_cell, null);
TextView textView = (TextView)gridViewItem.findViewById(R.id.grid_item_number);
textView.setText(mValues[position]);
EditText editText = (EditText)gridViewItem.findViewById(R.id.grid_item_label);
} else {
gridViewItem = (View) convertView;
}
gridViewItem.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Log.e("GRID", "onLongClick: " );
return true;
}
});
//Add an OnclickListener here
gridViewItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mListener != null){
mListener.onGridItemClick(v, position);
}
}
});
return gridViewItem;
}
public interface GridViewItemClickListener{
void onGridItemClick(View v, int index);
}
}
You can user click listeners inside the adapter it will work ,it should work like this
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
MyObject obj = myObjects.get(position);
if (convertView == null) {
gridView = inflater.inflate(R.layout.grid_cell, null);
String textColour = "#000000";
TextView textView = (TextView) gridView.findViewById(R.id.grid_item_label);
textView.setText(Html.fromHtml(String.format("<font color='%s'>%s</font>", textColour, obj.getValue())));
TextView superScriptTv = (TextView) gridView.findViewById(R.id.grid_item_number);
superScriptTv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// here you can use every item of grid acc to position
}
});
if (obj.getNumber() > 0) {
superScriptTv.setText(Html.fromHtml(String.format("<font>%s</font>", cell.getNumber())));
}
} else {
gridView = convertView;
}
gridView.setBackgroundColor(obj.getBackgroundColour());
return gridView;
}
how can the click listener work if you set the root element in GridCell.java as non-clickable ?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:padding="0dp" android:layout_margin="0dp"
android:focusable="false"
android:clickable="false"
android:focusableInTouchMode="false"
Remove those lines from each of your components in the GridCell.java
android:focusable="false"
android:clickable="false"
android:focusableInTouchMode="false"
I don't think this is required for GridView, but sometimes for RecyclerView it is required to have android:clickable="true" on the root componenent of GridCell.java
I've read some SO questions like this and this but still couldn't figure out whats wrong with my code.
I have a ListFragment, and each row has a TextView and a CheckBox.
Clicking the CheckBox is working, but clicking on the TextView does nothing, and OnListItemClick doesn't get called. I've also tried to dynamically add an OnClickListener, which make it work, but it's not the correct way to do it, and it also lacks the GUI feedback of the click (item being "highlighted" for a sec).
This is my textview_with_checkbox.XML I'm using for each item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:gravity="left"
android:descendantFocusability="blocksDescendants"
android:orientation="horizontal" >
<TextView
android:id="#+id/textview_event_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="3dp"
android:paddingTop="5dp"
android:focusable="true"
android:singleLine="false" />
<CheckBox
android:id="#+id/checkbox_for_event_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.05"
android:focusable="false"
android:clickable="false" />
</LinearLayout>
now the code:
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
displayEventsLogFiles();
}
#Override
public void onListItemClick(ListView l, View v, int position, long id)
{
super.onListItemClick(l, v, position, id);
String chosenItem = (String) getListAdapter().getItem(position);
mCallBack.onEventItemSelected(chosenItem);
}
static class myCustomAdapterViewHolder
{
public TextView eventName;
public CheckBox eventCheckBox;
}
private class myCustomAdapter extends ArrayAdapter<String>
{
private ArrayList<String> sortedList;
private Context m_oContext;
List<String> m_oValues = null;
public myCustomAdapter(Context cont, int viewResId, List<String> objects)
{
super(cont, viewResId, objects);
m_oContext = cont;
m_oValues = objects;
sortedList = new ArrayList<String>();
for (String str : objects)
sortedList.add(str);
java.util.Collections.sort(sortedList);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View l_oRowView = convertView;
myCustomAdapterViewHolder l_oInitializedViewHolder = null;
final int l_nPosition = position;
// Use convertView if possible, otherwise inflate a view:
if (l_oRowView == null)
{
LayoutInflater inflater = (LayoutInflater) m_oContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
l_oRowView = inflater.inflate(R.layout.textview_with_checkbox, parent, false);
// PlaceHolder pattern:
final myCustomAdapterViewHolder l_oViewHolder = new myCustomAdapterViewHolder();
l_oViewHolder.eventName = (TextView) l_oRowView.findViewById(R.id.textview_event_name);
l_oViewHolder.eventCheckBox = (CheckBox) l_oRowView.findViewById(R.id.checkbox_for_event_name);
l_oViewHolder.eventCheckBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CheckBox cb = (CheckBox)v;
//cb.setChecked(!cb.isChecked());
String l_sFilename = l_oViewHolder.eventName.getText().toString();
if (cb.isChecked())
{
if (!m_lstSelectedFilenames.contains(l_sFilename))
m_lstSelectedFilenames.add(l_sFilename);
}
else
{
if (m_lstSelectedFilenames.contains(l_sFilename))
m_lstSelectedFilenames.remove(l_sFilename);
}
}
});
l_oViewHolder.eventCheckBox.setFocusable(false);
//l_oViewHolder.eventCheckBox.setClickable(false);
// "Add" the viewHolder as a tag:
l_oRowView.setTag(l_oViewHolder);
l_oInitializedViewHolder = l_oViewHolder;
}
else
l_oInitializedViewHolder = (myCustomAdapterViewHolder) l_oRowView.getTag();
// By now, the rowView is initialized, just get the viewHolder and then get the views from it, to update:
//myCustomAdapterViewHolder l_oViewHolder = (myCustomAdapterViewHolder) l_oRowView.getTag();
/*l_oInitializedViewHolder.eventName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCallBack.onEventItemSelected((String)getListAdapter().getItem(l_nPosition));
}
});*/
l_oInitializedViewHolder.eventName.setText(m_oValues.get(position));
return l_oRowView;
//return super.getView();
}
public myCustomAdapter(Context cont, int viewResId, String[] strings)
{
this(cont, viewResId, Arrays.asList(strings));
}
#Override
public String getItem(int position)
{
return sortedList.get(position);
}
#Override
public int getPosition(String item)
{
return sortedList.indexOf(item);
}
}
What am I doing wrong here?
All I want is to be able to select "files" for deletion, using the CheckBoxes
Try only using only onclick for textview and checkbox, not onListItemClick -which you can remove- as well, so you should change some properties for the linear layout as well.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:gravity="left"
android:orientation="horizontal" >
<TextView
android:id="#+id/textview_event_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="3dp"
android:paddingTop="5dp"
android:focusable="true"
android:singleLine="false" />
<CheckBox
android:id="#+id/checkbox_for_event_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.05"
android:focusable="false"
android:clickable="false" />
</LinearLayout>
Implement in the adapter
// PlaceHolder pattern:
final myCustomAdapterViewHolder l_oViewHolder = new myCustomAdapterViewHolder();
l_oViewHolder.eventName = (TextView) l_oRowView.findViewById(R.id.textview_event_name);
l_oViewHolder.eventCheckBox = (CheckBox) l_oRowView.findViewById(R.id.checkbox_for_event_name);
l_oViewHolder.eventName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// your code for textview click
}
}
l_oViewHolder.eventCheckBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CheckBox cb = (CheckBox)v;
//cb.setChecked(!cb.isChecked());
String l_sFilename = l_oViewHolder.eventName.getText().toString();
if (cb.isChecked())
{
if (!m_lstSelectedFilenames.contains(l_sFilename))
m_lstSelectedFilenames.add(l_sFilename);
}
else
{
if (m_lstSelectedFilenames.contains(l_sFilename))
m_lstSelectedFilenames.remove(l_sFilename);
}
}
});
l_oViewHolder.eventCheckBox.setFocusable(false);
add following attribute:
android:focusable="false"
android:clickable="false"
for example in my xml file:
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:textAppearance="?android:attr/textAppearanceLarge"
android:gravity="center_vertical"
android:button="?android:attr/listChoiceIndicatorSingle"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:buttonTint="#color/gray"
android:focusable="false"
android:clickable="false"
/>
and in my code:
public class MyTestFragment extends ListFragment {
.....
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
}
}
Im new in android programing, I want make calculating with multiple spinner that have value string and edit text. and proccess with button click and show on text view. please healp me to fix so i can learn next subject.
THx
My activity .java code:
public class MainActivity extends Activity {
private EditText jumlah;
String[] spinnerValues = { "Bakso", "Es Buah" };
String[] spinnerSubs = {"10000", "8000" };
int total_images[] = { R.drawable.bakso, R.drawable.es_buah };
private Button button1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner mySpinner = (Spinner) findViewById(R.id.spinner_show);
mySpinner.setAdapter(new MyAdapter(this, R.layout.menu_resto,
spinnerValues));
jumlah = (EditText) findViewById(R.id.editText1);
button1 = (Button) findViewById(R.id.button1);
initButton();
}
private void initButton() {
button1.setOnClickListener(new OnClickListener() {
// this one performs an action when our button is clicked. it performs whatever is below
#Override
public void onClick(View v) {
// String strA = i want call the spinersubs value that chsoed. how ?
String strB = jumlah.getText().toString();
Double dblAnswer = doCalc(strA, strB);
TextView lblAnswer = (TextView) findViewById(R.id.lblAnswer);
// the disadvantage is that we can't do anything to it outside of this curly
// in general it's wasteful to use fields when you can suffice with local variable
String answer = String.valueOf(dblAnswer);
// we get our answer and turn it to a string.
lblAnswer.setText(answer);
// finally we set our result to the textView.
}
});
}
public double doCalc(String a, String b) {
double dblA = Double.parseDouble(a);
double dblB = Double.parseDouble(b);
return dblA * dblB;
}
class MyAdapter extends ArrayAdapter<String> {
public MyAdapter(Context ctx, int txtViewResourceId, String[] objects) {
super(ctx, txtViewResourceId, objects);
}
#Override
public View getDropDownView(int position, View cnvtView, ViewGroup prnt) {
return getCustomView(position, cnvtView, prnt);
}
#Override
public View getView(int pos, View cnvtView, ViewGroup prnt) {
return getCustomView(pos, cnvtView, prnt);
}
public View getCustomView(int position, View convertView,
ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View mySpinner = inflater.inflate(R.layout.menu_resto, parent,
false);
TextView main_text = (TextView) mySpinner
.findViewById(R.id.text_main_seen);
main_text.setText(spinnerValues[position]);
TextView subSpinner = (TextView) mySpinner
.findViewById(R.id.sub_text_seen);
subSpinner.setText(spinnerSubs[position]);
ImageView left_icon = (ImageView) mySpinner
.findViewById(R.id.left_pic);
left_icon.setImageResource(total_images[position]);
return mySpinner;
}
Here my XML
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="X - Resto Menu"
android:textSize="30px" />
<Spinner
android:id="#+id/spinner_show"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="100px"
android:drawSelectorOnTop="true" />
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/spinner_show"
android:layout_centerHorizontal="true"
android:layout_marginTop="46dp"
android:ems="10" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/spinner_show"
android:layout_centerHorizontal="true"
android:layout_marginTop="23dp"
android:text="Jumlah Pesanan" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/editText1"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:onClick="#string/hitung"
android:text="#string/pesan" />
<TextView
android:id="#+id/lblAnswer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/editText1"
android:layout_centerHorizontal="true"
android:text="" />
You need to implement CustomOnItemSelectedListener for Spinner like
public class CustomOnItemSelectedListener implements OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
Toast.makeText(parent.getContext(),
"OnItemSelectedListener : " + parent.getItemAtPosition(pos).toString(),
Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
and then set this Listener to your Spinner like
mySpinner.setOnItemSelectedListener(new CustomOnItemSelectedListener());
and in Button click you'll get a Spinner selected value like
btnSubmit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MyAndroidAppActivity.this,
"OnClickListener : " +
"\nSpinner : "+ String.valueOf(mySpinner.getSelectedItem())
,Toast.LENGTH_SHORT).show();
}
});
Go to this for Tutorial
I am using a ListView with a custom adapter for displaying items as pairs of title/subtitle TextViews.
Unfortunately, I can select an item just by clicking on its upper half, the one occupied by the title
Here is the code I am using:
journal_list.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawSelectorOnTop="false"
android:background="#fff"
android:cacheColorHint="#fff"
android:paddingBottom="6dp"
/>
journal_list_item.xml for the list item's layout
<?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"
android:descendantFocusability="blocksDescendants"
>
<TextView
android:id="#+id/journal_entry_date"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textColor="#000"
android:textSize="18sp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
/>
<TextView
android:id="#+id/journal_content"
android:paddingLeft="28dp"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textSize="16sp"
android:textColor="#555"
android:inputType="textMultiLine"
android:maxLines="2"
android:minLines="1"
android:layout_below="#id/journal_entry_date"
android:layout_alignParentLeft="true"
/>
Also the code for the adapter:
private class JournalAdapter extends ArrayAdapter<JournalEntry> {
Context ctxt;
public JournalAdapter(Context ctxt) {
super(ctxt, R.layout.journal_list_item);
this.ctxt = ctxt;
}
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
JournalHolder holder;
if (row == null) {
row = ((LayoutInflater)ctxt.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).
inflate(R.layout.journal_list_item, parent, false);
holder = new JournalHolder(row);
row.setTag(holder);
} else {
holder = (JournalHolder) row.getTag();
}
JournalEntry crt = getItem(position);
holder.getDate().setText(crt.dateWritten);
holder.getContent().setText(crt.content);
return row;
}
}
private static class JournalHolder {
private TextView date;
private TextView content;
private View base;
public JournalHolder(View base) {
this.base = base;
}
public TextView getDate() {
if (date == null)
date = (TextView) base.findViewById(R.id.journal_entry_date);
return date;
}
public TextView getContent() {
if (content == null)
content = (TextView) base.findViewById(R.id.journal_content);
return content;
}
}
Code from the ListActivity's onCreate() method:
private JournalAdapter adapter;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.journal_list);
adapter = new JournalAdapter(this);
setListAdapter(adapter);
registerForContextMenu(getListView());
}
Also, I am calling a method called updateList() in onResume()
private void updateList() {
adapter.clear();
Cursor cursor = helper.listJournal(start, end);
cursor.moveToFirst();
JournalEntry crt;
while (!cursor.isAfterLast()) {
crt = new JournalEntry();
crt.dateWritten = cursor.getString(cursor.getColumnIndex("date_written"));
crt.content = cursor.getString(cursor.getColumnIndex("content"));
crt.id = cursor.getInt(cursor.getColumnIndex("entry_id"));
adapter.add(crt);
cursor.moveToNext();
}
cursor.close();
adapter.notifyDataSetChanged();
}
List item clicking is handled in the onListItemClick of my ListActivity, as follows:
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = new Intent(this, JournalEditor.class);
intent.setAction(Intent.ACTION_EDIT);
intent.putExtra("entry_id", adapter.getItem(position).id);
startActivity(intent);
}
Apparently, I am forgetting something important, and that's why this whole weird thing happens.
I have found a similar discussion here: http://groups.google.com/group/android-developers/browse_thread/thread/5636c8ea74033657 but it wasn't very helpful.
The problem may be from the clicking of the textviews. When you set the views of the listview items as clickable, they override the click of the listview item and the click will only work when the specific view of the item is clicked.
If this is the case, do the following for your two textviews in the getView() function:
TextView tv;
tv.setFocusable(false);
tv.setClickable(false);
Then set the listview to clickable: listView1.setClickable(true);