I try to display some items in a Gridview and set button click listener. When the item was clicked, it shows a dialog box, if clicking yes, it will change the Imageview.
java coding
public class table extends AppCompatActivity implements AdapterView.OnItemClickListener{
GridView gridView;
my_adapter my_adapter;
String table_names[]={"1a","1b","1c","1d","2a","2b","2c","2d","3a","3b","3c","3d"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_table);
gridView=(GridView)findViewById(R.id.gridview);
my_adapter=new my_adapter(this,table_names);
gridView.setAdapter(my_adapter);
gridView.setOnItemClickListener(this);
}
#Override
public void onItemClick(final AdapterView<?> adapterView, final View view, final int i, long l) {
new AlertDialog.Builder(this)
.setTitle("Table number: "+adapterView.getItemAtPosition(i).toString())
.setMessage("Open Table?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
my_adapter.change_img(); // change to new image
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
my_adapter.change_img2(); // change back to original image
}
})
.show();
}
}
class my_adapter extends BaseAdapter{
ImageView imageView;
LayoutInflater inflater=null;
Context ctx;
String table_names[];
ArrayList store_table_no;
my_adapter(Context ctx, String table_names[]){
this.ctx=ctx;
this.table_names=table_names;
store_table_no=new ArrayList<Integer>();
for (int i=0;i<table_names.length;i++){
store_table_no.add(table_names[i]);
}
}
#Override
public int getCount() {
return store_table_no.size();
}
#Override
public Object getItem(int i) {
return store_table_no.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
View row=view;
if(row==null){
inflater=(LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row=inflater.inflate(R.layout.single,null);
}
TextView tv_table_no=(TextView)row.findViewById(R.id.table_no);
imageView=(ImageView)row.findViewById(R.id.imageView);
tv_table_no.setText(""+store_table_no.get(i));
return row;
}
public void change_img(){
imageView.setImageResource(R.drawable.table_full);
}
public void change_img2(){
imageView.setImageResource(R.drawable.table3d2);
}
}
single.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="101"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/table_no"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="22sp" />
<ImageView
app:srcCompat="#drawable/table"
android:id="#+id/imageView"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_width="130dp"
android:layout_height="100dp" />
</RelativeLayout>
Here is a screenshot, please have a look
It simply doesn't change the imageview. Looks like something is wrong with my coding. anyone knows what's happening ?
You are implementing GridView's OnItemClickListener to show a dialog and getting decision from user for each item. When you are showing up a dialog it needs to update current clicked item of grid. But in your case you have change_img() in adapter. No position specification is given to the adapter.
To make it work, move your logic from activity to adapter. Handle the click events with the positions.
In your activity,
public class table extends AppCompatActivity{
GridView gridView;
my_adapter my_adapter;
String table_names[] = {"1a", "1b", "1c", "1d", "2a", "2b", "2c", "2d", "3a", "3b", "3c", "3d"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid);
gridView = (GridView) findViewById(R.id.grid);
my_adapter = new my_adapter(this, table_names);
gridView.setAdapter(my_adapter);
}
class my_adapter extends BaseAdapter {
LayoutInflater inflater = null;
Context ctx;
String table_names[];
ArrayList<String> store_table_no;
my_adapter(Context ctx, String table_names[]) {
this.ctx = ctx;
this.table_names = table_names;
store_table_no = new ArrayList<>();
store_table_no.addAll(Arrays.asList(table_names));
}
#Override
public int getCount() {
return store_table_no.size();
}
#Override
public Object getItem(int i) {
return store_table_no.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(final int i, View view, ViewGroup viewGroup) {
View row = view;
if (row == null) {
inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.single, null);
}
RelativeLayout layout = (RelativeLayout) row.findViewById(R.id.relative_layout);
TextView tv_table_no = (TextView) row.findViewById(R.id.table_no);
final ImageView imageView = (ImageView) row.findViewById(R.id.imageView);
tv_table_no.setText(store_table_no.get(i));
layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new AlertDialog.Builder(GridActivity.this)
.setTitle("Table number: " + store_table_no.get(i))
.setMessage("Open Table?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
imageView.setImageResource(R.mipmap.ic_launcher);
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
imageView.setImageResource(R.drawable.icon);
}
})
.show();
}
});
return row;
}
}
}
In your xml file add id to Parent RElative Layout as follows,
single.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:layout_width="match_parent"
android:id="#+id/relative_layout"
android:clickable="true"
android:layout_height="match_parent">
<TextView
android:text="101"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/table_no"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="22sp" />
<ImageView
app:srcCompat="#drawable/table"
android:id="#+id/imageView"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_width="130dp"
android:layout_height="100dp" />
</RelativeLayout>
I hope it will help you.
Related
I have a database, and I am trying to show the columns on cardview on my app.
Nothing wrong database side I guess. I have checked it, for example I can add items to the database. I can login-register. But when I add my items, I should be seeing them on the cardview after addition process.
When I add item on the database, it goes back to the recyclerview layout but shows nothing. Only an empty page.
No errors on the debug process until now.
Here is my cardview layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:padding="15dp"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="#+id/itemName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stock Name"
android:textColor="#color/colorPrimary" />
<TextView
android:id="#+id/barcode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stock Code" />
<TextView
android:id="#+id/tvQuantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Quantity" />
<TextView
android:id="#+id/tvPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Price" />
<TextView
android:id="#+id/tvCost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cost" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
recyclerlayout:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
RECYCLER.JAVA
public class recycler extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private DatabaseHelper myDb;
private itemAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler);
myDb = new DatabaseHelper(this);
Intent intent =getIntent();
mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.home_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.addMenu:
goToAddActivity();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void goToAddActivity(){
Intent intent = new Intent(recycler.this, add.class);
startActivity(intent);
}
}
itemAdapter.java
public class itemAdapter extends RecyclerView.Adapter<itemAdapter.ViewHolder> {
private List<list> mItemsList;
private Context mContext; //to inflate list layout
private RecyclerView mRecyclerV;
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView nameTxt;
public TextView quantityTxt;
public TextView priceTxt;
public TextView costTxt;
public TextView barcodeTxt;
public View layout;
public ViewHolder( View v) {
super(v);
layout = v;
nameTxt = (TextView) v.findViewById(R.id.itemName);
quantityTxt = (TextView) v.findViewById(R.id.tvQuantity);
priceTxt = (TextView) v.findViewById(R.id.tvPrice);
costTxt = (TextView) v.findViewById(R.id.tvCost);
barcodeTxt = (TextView) v.findViewById(R.id.barcode);
}
}
public void add(int position, list list) {
mItemsList.add(position, list);
notifyItemInserted(position);
}
public void remove(int position) {
mItemsList.remove(position);
notifyItemRemoved(position);
}
// Provide a suitable constructor (depends on the kind of dataset)
public itemAdapter(List<list> myDataset, Context context, RecyclerView recyclerView) {
mItemsList = myDataset;
mContext = context;
mRecyclerV = recyclerView;
}
// Create new views (invoked by the layout manager)
#Override
public itemAdapter.ViewHolder onCreateViewHolder( ViewGroup parent, int viewType) {
//create a new view
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View v =inflater.inflate(R.layout.activity_list, parent, false);
// set the view's size, margins, paddings and layout parameters
return new ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
final list list = mItemsList.get(position);
holder.nameTxt.setText("Stock Name: " + list.getName());
holder.barcodeTxt.setText("Barcode: " + list.getBarcode());
holder.quantityTxt.setText("Quantity: " + list.getQuantity());
holder.priceTxt.setText("Price: " + list.getPrice());
holder.costTxt.setText("Cost: " + list.getCost());
holder.layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("Choose option");
builder.setMessage("Update or delete stock?");
builder.setPositiveButton("Update", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//go to update activity
goToUpdateActivity(list.getId());
}
});
builder.setNeutralButton("Delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
DatabaseHelper dbHelper = new DatabaseHelper(mContext);
dbHelper.deleteRecord(list.getId(), mContext);
mItemsList.remove(position);
mRecyclerV.removeViewAt(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mItemsList.size());
notifyDataSetChanged();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
});
}
private void goToUpdateActivity(long listID){
Intent goToUpdate = new Intent(mContext, update.class);
goToUpdate.putExtra("listID", listID);
mContext.startActivity(goToUpdate);
}
#Override
public int getItemCount() {
return mItemsList.size();
}
}
I tried all the solution that i found here in the stackoverflow but it seems like none of them work.
Here is my main activity:
public class MerchantLocatorActivity extends AppCompatActivity implements OnMapReadyCallback {
public void init(){
merchantLocatorResponseObject = new MerchantLocatorResponse();
merchantLocatorResponseObject.setTitle("Spherical");
merchantLocatorResponseObject.setAddress("8007 Pioneer St, Kapitolyo, Mandaluyong, 1550 Metro Manila");
merchantLocatorResponseObject.setLatitude( 14.573249);
merchantLocatorResponseObject.setLongitude(121.057022);
merchantLocatorObjectArray.add(merchantLocatorResponseObject);
merchantLocatorResponseObject = new MerchantLocatorResponse();
merchantLocatorResponseObject.setTitle("Globe");
merchantLocatorResponseObject.setAddress("SCT, 584 Shaw Blvd, Mandaluyong, 1552 Metro Manila");
merchantLocatorResponseObject.setLatitude(14.585095);
merchantLocatorResponseObject.setLongitude(121.048893);
merchantLocatorObjectArray.add(merchantLocatorResponseObject);
merchantLocatorResponseObject = new MerchantLocatorResponse();
merchantLocatorResponseObject.setTitle("Sparndium");
merchantLocatorResponseObject.setAddress("Xavier, San Juan, 1502 Metro Manila");
merchantLocatorResponseObject.setLatitude(14.601918);
merchantLocatorResponseObject.setLongitude(121.042169);
merchantLocatorObjectArray.add(merchantLocatorResponseObject);
addMarker();
}
#OnClick(R.id.fab)
public void showAccToDialog() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
View alertView = LayoutInflater.from(this).inflate(R.layout.dialog_biller, null);
alertDialogBuilder.setView(alertView);
final AlertDialog dialog = alertDialogBuilder.create();
dialog.show();
final ListView listViewBillers = (ListView) dialog.findViewById(R.id.biller_institutions_listview);
if (listViewBillers != null) {
MerchantLocatorAdapter adapter = new MerchantLocatorAdapter(
this, R.layout.merchant_locator_adapter, merchantLocatorObjectArray);
listViewBillers.setAdapter(adapter);
listViewBillers.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
geoLocate(merchantLocatorObjectArray,position);
DebugUtils.log("TESTTESTACTIVITYZXC");
DebugUtils.showToast(MerchantLocatorActivity.this,"HAHAHAH");
dialog.dismiss();
}
});
final EditText mSearchedittext = (EditText) dialog.findViewById(R.id.search_edittext);
mSearchedittext.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
final ArrayList<MerchantLocatorResponse> searchResultObject = new ArrayList<>();
searchResultObject.clear();
for (int hay = 0; hay <= merchantLocatorObjectArray.size() - 1; hay++) {
if ( merchantLocatorObjectArray.get(hay).getTitle().toLowerCase().contains(charSequence)) {
searchResultObject.add( merchantLocatorObjectArray.get(hay));
}
}
MerchantLocatorAdapter adapter = new MerchantLocatorAdapter(
MerchantLocatorActivity.this, R.layout.merchant_locator_adapter, searchResultObject);
listViewBillers.setAdapter(adapter);
listViewBillers.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long arg) {
geoLocate(searchResultObject,position);
dialog.dismiss();
}
});
}
#Override
public void afterTextChanged(Editable editable) {
}
});
}
}
}
i remove some part of the code because i think it's un necessary to include but let me know if there's some part that i need some clarification.
currently in my main activity, i'm calling a dialog that contains a listview and in my listview i have items.
My problem is i can't select any of my items even thought i have my setOnitemclick listener.
here is my adapter:
public class MerchantLocatorAdapter extends BaseAdapter {
private int resourceLayout;
private Context mContext;
ArrayList<MerchantLocatorResponse> merchantLocatorarray = new ArrayList<>();
public MerchantLocatorAdapter(Context context, int resource, ArrayList<MerchantLocatorResponse> merchantLocatorResponsesobjectArray) {
this.resourceLayout = resource;
this.mContext = context;
this.merchantLocatorarray = merchantLocatorResponsesobjectArray;
}
#Override
public int getCount() {
return merchantLocatorarray.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(mContext.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resourceLayout, parent, false);
}
TextView tt1 = (TextView) convertView.findViewById(R.id.field_name_textview);
TextView tt2 = (TextView) convertView.findViewById(R.id.field_value_textview);
ImageButton direction = (ImageButton) convertView.findViewById(R.id.direction);
tt1.setText(merchantLocatorarray.get(position).getTitle());
tt2.setText(merchantLocatorarray.get(position).getAddress());
return convertView;
}
}
here is my layout for my adapter:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="8dp"
android:elevation="3dp">
<LinearLayout
android:id="#+id/card_overflow"
android:focusable="true"
android:clickable="true"
android:background="#fff"
android:paddingLeft="16dp"
android:paddingRight="0dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="1">
<TextView
android:id="#+id/field_name_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_toLeftOf="#+id/branch_btns"
android:layout_alignParentLeft="true"
android:textSize="17sp"
android:textStyle="bold"
android:textColor="#color/edittext_text"
android:text="test"/>
<LinearLayout
android:id="#+id/branch_btns"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:orientation="horizontal"
>
<ImageButton
android:id="#+id/direction"
android:layout_width="50sp"
android:layout_height="wrap_content"
android:src="#drawable/ic_direction"
android:scaleType="fitCenter"
android:background="#color/translucent_clear_bg"
/>
<ImageButton
android:id="#+id/btn_branch_phone"
android:layout_width="50sp"
android:layout_height="wrap_content"
android:src="#drawable/ic_call_phone"
android:scaleType="fitCenter"
android:background="#color/translucent_clear_bg"
/>
</LinearLayout>
</RelativeLayout>
<View
android:id="#+id/seperator"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginBottom="5dp"
android:background="#android:color/darker_gray"
android:visibility="gone"
android:layout_marginTop="2dp"/>
<TextView
android:id="#+id/field_value_textview"
android:textSize="14sp"
android:textColor="#color/edittext_tint"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="test"/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
i tried every solution that i found here in stackoverflow, and yet i can't still click my item. so please don't mark this as a duplicate.
if there's any part of the code that need clarification, please leave a comment and i'll answer as soon as possible. thanks.
Try to use Observable in you custom adapter:
// Define
private final PublishSubject<MerchantLocatorResponse> onItemClick = PublishSubject.create();
// Create the observable method
public Observable<ConversationMessage> getObservable(){
return onItemClick;
}
// Set the onClickListener into getView()
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onItemClick.onNext(merchantLocatorarray.get(position));
}
});
Then, in your main activity listen to it and handle the click:
#OnClick(R.id.fab)
public void showAccToDialog() {
// bla bla bla
listViewBillers.setAdapter(adapter);
listViewBillers.getObservable().subscribe(geoLocate);
// bla bla bla
}
Consumer<MerchantLocatorResponse> geoLocate = new Consumer<MerchantLocatorResponse>() {
#Override
public void accept(MerchantLocatorResponse mlr) {
// Code after click event
}
};
Add those library in your gradle:
implementation "io.reactivex.rxjava2:rxjava:2.1.5"
implementation "io.reactivex.rxjava2:rxandroid:2.0.1"
Add convertView.setOnclickListener() in your code. Try below code in your adapter
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(mContext.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resourceLayout, parent, false);
}
TextView tt1 = (TextView) convertView.findViewById(R.id.field_name_textview);
TextView tt2 = (TextView) convertView.findViewById(R.id.field_value_textview);
ImageButton direction = (ImageButton) convertView.findViewById(R.id.direction);
tt1.setText(merchantLocatorarray.get(position).getTitle());
tt2.setText(merchantLocatorarray.get(position).getAddress());
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, String.valueOf(position), Toast.LENGTH_SHORT).show();
}
});
return convertView;
} }
I want to create a listview that displays the same clickable icon several times. I tried many ways, including a custom adapter with layout inflater but failed... At this point my ListView displays numbers instead of the icon. Can you help me please? here is my code
public class UserSelectionActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
static ArrayList<Integer> arrayOfIcons = new ArrayList<Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_selection);
arrayOfIcons.clear();
for (int i=0; i<3; i++) {arrayOfIcons.add(R.drawable.edit);}
ArrayAdapter<Integer> adapter2 = new ArrayAdapter<Integer>(this, android.R.layout.simple_list_item_1, arrayOfIcons);
ListView listView2 = (ListView) findViewById(R.id.usersListView2);
listView2.setAdapter(adapter2);
listView2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//TODO
}
});
}
}
I don't do anything in onResume method, that's why I didn't share it
And my xml file :
<?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="match_parent">
<ListView
android:id="#+id/usersListView2"
android:layout_width="80dp"
android:layout_height="450dp"
android:layout_alignParentEnd="true"
android:paddingTop="4dip"
android:paddingBottom="3dip" />
</RelativeLayout>
Hy, I suggest you to create a custom adapter:
1) create your list_item:
In res -> layout create a new file named list_item.xml. It contains only one imageView inserted into a ConstraintLayout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageViewIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="#mipmap/ic_launcher" />
2) In your activity_main.xml you have to inser your listView:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="#+id/listViewIcon"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
3) Now you have to create a new class call, for example, IconAdapter, where you create your custom adapter:
public class IconAdapter extends BaseAdapter {
Context context;
List<Integer> iconIDList;
/**
*
* #param context = activity context
* #param iconIDList = list with icon's id
*/
public IconAdapter(Context context, List<Integer> iconIDList) {
this.context = context;
this.iconIDList = iconIDList;
}
#Override
public int getCount() {
//return the size of my list
return iconIDList.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
//inflate my view
if (convertView == null) {
LayoutInflater inflater;
inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.list_item, null);
}
//istantiate my imageView
ImageView imageView = convertView.findViewById(R.id.imageViewIcon);
//set imageView's icon
imageView.setImageResource(iconIDList.get(i));
//return my view
return convertView;
}
}
4) Now in your MainActivity, put all together:D
public class MainActivity extends AppCompatActivity {
List<Integer> iconIDList;
IconAdapter iconAdapter;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//istantiate my components
iconIDList = new ArrayList<>();
listView = findViewById(R.id.listViewIcon);
iconAdapter = new IconAdapter(this, iconIDList);
int myIcon = R.drawable.ic_launcher_background;
//populate the list with icon's id
for (int i = 0; i < 5; i++) {
iconIDList.add(myIcon);
}
//set my custom adapter to the listView
listView.setAdapter(iconAdapter);
//set clickListner to the elements of my listView
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//i is the index of the clicked element
Toast.makeText(MainActivity.this, "Click on element n. " + i, Toast.LENGTH_SHORT).show();
}
});
}
}
I hope that can help you!!! Good job!! If you have a question, comment my answer!!
In your comment you ask me how to add one listener for the name (textView) clicked and one for the icon clicked.
1) modify your list_item.xml file. Now we can use:
a LinearLayout instead of ConstraintLayout;
a textView;
a ImageButton instead of ImageView.
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:descendantFocusability="blocksDescendants" > <!--this is very important to detect click-->
<TextView
android:id="#+id/textViewIcon"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:gravity="left|center"
android:text="TextView"
android:textSize="24sp" />
<ImageButton
android:id="#+id/imageButtonIcon"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_weight="1"
app:srcCompat="#mipmap/ic_launcher" />
</LinearLayout>
2) Is better if you create a class that contains your data. We can call this class IconData:
public class IconData {
int iconID;
String text;
//constructor
public IconData(int iconID, String text) {
this.iconID = iconID;
this.text = text;
}
//getter and setter
public int getIconID() {
return iconID;
}
public void setIconID(int iconID) {
this.iconID = iconID;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
3) Now we have to change our IconAdapter.
We'll add an Interface to detect clicks on the ImageButton;
We'll change the list's data type;
We'll instatiate the newest TextView and ImageButton:
//create custom adapter -> I extend my class using BaseAdapter
public class IconAdapter extends BaseAdapter {
//create an interface to comunicate the clicks on the imageButton
public interface MyIconAdapterInterface {
void setOnClickListnerMyImageButton (int position);
}
Context context;
//change the list's name and data type
List<IconData> iconIDTextList;
MyIconAdapterInterface myIconAdapterInterface;
/**
* #param context = activity context
* #param iconIDTextList = list with icon's id and text
* #param myIconAdapterInterface = the interface that mainActivity will implements
*/
public IconAdapter(Context context, List<IconData> iconIDTextList, MyIconAdapterInterface myIconAdapterInterface) {
this.context = context;
this.iconIDTextList = iconIDTextList;
this.myIconAdapterInterface = myIconAdapterInterface;
}
#Override
public int getCount() {
//return the size of my list
return iconIDTextList.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(final int i, View convertView, ViewGroup viewGroup) {
//inflate my view
if (convertView == null) {
LayoutInflater inflater;
inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.list_item, null);
}
//istantiate my imageView and textView
ImageButton imageButton = convertView.findViewById(R.id.imageButtonIcon);
TextView textView = convertView.findViewById(R.id.textViewIcon);
//set imageView's button
int image = iconIDTextList.get(i).getIconID();
imageButton.setImageResource(image);
//set text
String text = iconIDTextList.get(i).getText();
textView.setText(text);
//setOnclickListner on my imageButton
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//pass the position of my clicks to the myIconAdapterInterface
myIconAdapterInterface.setOnClickListnerMyImageButton(i);
}
});
return convertView;
}
}
4) Finally we have to change the MainActivity.java's code:
implement our class with the new interface that we have create in our IconAdapter;
modify our list data type;
pass the newest list and the interface to the IconAdapter;
implement the interface's methods.
//I implement my MainActivity with IconAdapter.MyIconAdapterInterface. I create this interface
//in the iconAdapter class
public class MainActivity extends AppCompatActivity implements IconAdapter.MyIconAdapterInterface {
//change to iconIDTextList and change List data type
List<IconData> iconIDTextList;
IconAdapter iconAdapter;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//istantiate my components
iconIDTextList = new ArrayList<>();
listView = findViewById(R.id.listViewIcon);
//the second "this" is refer to the IconAdapter.MyIconAdapterInterface
iconAdapter = new IconAdapter(this, iconIDTextList, this);
int myIcon = R.drawable.ic_launcher_background;
String myText = "Hello! ";
//populate the list with icon's id and text
for (int i = 0; i < 5; i++) {
iconIDTextList.add(new IconData(myIcon, myText + i));
}
//set my custom adapter to the listView
listView.setAdapter(iconAdapter);
//set clickListner to the elements of my listView
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//i is the index of the clicked element
Toast.makeText(MainActivity.this, "Click on element n. " + i, Toast.LENGTH_SHORT).show();
}
});
}
//this is IconAdapter.MyIconAdapterInterface's method that I have to implement
#Override
public void setOnClickListnerMyImageButton(int position) {
//position = click's position
Toast.makeText(this, "Click on image n. "
+ position, Toast.LENGTH_SHORT).show();
}
}
Good Job!!
I created a custom view with a edit text field and a button. I want to delete an item from listview by clicking on a button.
The code for the custom view:
<?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="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delete"
android:id="#+id/delete_btn"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/player_name_txt"
android:textColor="#ffffff"
android:editable="false"
android:background="#5eb8ed"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignBottom="#+id/delete_btn"
android:layout_toLeftOf="#+id/delete_btn"
android:layout_toStartOf="#+id/delete_btn" />
</RelativeLayout>
The code for the adapter and list view:
inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
playerListView = (ListView)this.findViewById(android.R.id.content).getRootView().findViewById(R.id.player_list);
playerListAdapter = new ArrayAdapter(this,R.layout.player_item,R.id.player_name_txt, new ArrayList<String>(){});
playerListView.setAdapter(playerListAdapter);
The Code I tried:
public void removePlayer(View v)
{
EditText pairedEdit = (EditText)findViewById(R.id.player_name_txt);
String name = pairedEdit.getText().toString();
playerListAdapter.remove(name);
playerListAdapter.notifyDataSetChanged();
}
Right now it removes the first item in the list view.
AlertDialog.Builder addPlayerBuilder = new AlertDialog.Builder(this);
final View customView = inflater.inflate(R.layout.add_player,null);
final EditText usernameEdit = (EditText)customView.findViewById(R.id.username_edit);
addPlayerBuilder.setView(customView);
addPlayerBuilder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
String name = usernameEdit.getText().toString();
playerListAdapter.add(name);
playerListAdapter.notifyDataSetChanged();
dialog.dismiss();
}
});
addPlayerBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog dialog = addPlayerBuilder.create();
dialog.show();
In your button of custom layout place a onclicklistener which would remove the element from the arraylist by remove() function on the basis of its position and then call notifyDataSetInvalidated()
Use this:
Button b2 = (Button) row.findViewById(R.id.button1);
b2.setTag(arg0);
b2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
int pos = (int)arg0.getTag();
lista.remove(pos);
SunetePreferateAdaptor.this.notifyDataSetChanged(); }
});
In adapter class on delete_btn click you have to call remove method :
public class yourAdapter extends BaseAdapter {
private static LayoutInflater inflater = null;
private Activity context;
private ArrayList<yourBean> arrList;
public yourAdapter(Activity context,
ArrayList<yourBean> arrList) {
this.context = context;
this.arrList = arrList;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return arrList.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_row,
null);
viewHolder.delete_btn= (Button) convertView
.findViewById(R.id.delete_btn);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.delete_btn.setTag(position);
viewHolder.delete_btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
arrayList.remove(position);
notifyDataSetChanged();
}
});
return convertView;
}
static class ViewHolder {
Button delete_btn;
}
}
I've successfully managed to extend a CursorAdapter and change the bindView- and newView-methods to be able to have clickable buttons inside my list. The button (which actually is a clickable ImageView) uses a selector as a backgroundresource, and everything works fine except that when I click the list-item-view, the selector of the button/imageview is activated and hence it appears as if I clicked the button/imageview even though I didn't. The method inside the onclicklistener that's bound to the button/imageview though, is not activated when clicking the list-item-view, so that works properly, it's only the selector. Here is my CustomCursorAdapter:
public class CustomCursorAdapter extends CursorAdapter {
Context context;
LayoutInflater inflater;
AlertDialog.Builder builder;
public CustomCursorAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, flags);
this.context = context;
inflater = LayoutInflater.from(context);
}
#Override
public void bindView(View view, Context c, Cursor cursor){
ViewHolder holder = (ViewHolder) view.getTag();
final Context context = c;
final String name = cursor.getString(cursor.getColumnIndex("name"));
final String number = cursor.getString(cursor.getColumnIndex("number"));
final String mail = cursor.getString(cursor.getColumnIndex("mail"));
holder.getTvName().setText(name);
holder.getTvNumber().setText(number);
holder.getTvMail().setText(mail);
int row_id = cursor.getInt(cursor.getColumnIndex("_id"));
holder.getCallButton().setTag(row_id);
holder.getCallButton().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
builder = new AlertDialog.Builder(context);
builder.setMessage("Call " + name + "?")
.setPositiveButton("Call", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
String uri = "tel:" + nummer.trim();
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse(uri));
context.startActivity(intent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
builder.create().show();
}
});
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View convertView = inflater.inflate(R.layout.contact_list_row, parent, false);
ViewHolder holder = new ViewHolder();
holder.setCallButton((ImageView) convertView.findViewById(R.id.bCall));
holder.setTvName((TextView) convertView.findViewById(R.id.tvName));
holder.setTvNumber((TextView) convertView.findViewById(R.id.tvNumber));
holder.setTvMail((TextView) convertView.findViewById(R.id.tvMail));
convertView.setTag(holder);
return convertView;
}
public static class ViewHolder {
private TextView tvName, tvNumber, tvMail;
private ImageView bCall;
public ImageView getCallButton() {
return bCall;
}
public void setCallButton(ImageView bCall) {
this.bCall = bCall;
}
public TextView getTvName() {
return tvName;
}
public void setTvName(TextView tvName) {
this.tvName = tvName;
}
public TextView getTvNumber() {
return tvNumber;
}
public void setTvNumber(TextView tvNumber) {
this.tvNumber = tvNumber;
}
public TextView getTvMail() {
return tvMail;
}
public void setTvMail(TextView tvMail) {
this.tvMail = tvMail;
}
}
}
This is the listView-XML:
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cacheColorHint="#android:color/transparent"
android:listSelector="#android:color/transparent" />
And the contact_list_row.XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/list_background"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvMail"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<ImageView
android:id="#+id/bCall"
android:background="#drawable/button"
android:clickable="true"
android:src="#drawable/ic_clean_phone" />
Selector:
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="#drawable/h_main_button_background_pressed"></item>
<item android:drawable="#drawable/h_main_button_background"></item>
</selector>
If you find any other errors or unnecessary code, I'm very thankful for that too!