I have created a custom ListView, and populated with an ArrayList of objects. It also has a checkbox, to allow the user to select certain items, and then on a button click do something with them.
My question is: How to iterate through the ListView code-side?
I've looked at the docs for ListView but can't find a method that looks as if it iterates through. Do I need to implement this in my CustomArrayAdapter??
You can use this. You shoudn't implement nothing from nessesary methods in CustomAdapter.
private void ButtonClick() {
View v;
CheckBox chBox;
for (int i = 0; i < myList.getCount(); i++) {
v = myList.getAdapter().getView(i, null, null);
chBox = (chBox) v.findViewById(R.id.checkBox);//your xml id value for checkBox.
if (chBox.isChecked()) {
doSomething();
}
}
....
}
I would not advice to use Anatol's method as this will create new views for each item. The best way to approach this would be to handle the click of the check box and update your model accordingly. Then you can do something like this:
ListAdapter adapter = myList.getAdapter();
for (int i = 0; i < adapter.getCount(); i++) {
if (adapter.getItem(i).isChecked()) {
doSomething();
}
}
Note that isChecked need to be created in your model class. Please let me know if you have any questions.
Related
I want to get the position of a item in the list view and use it in a if.
Now i am going through the listview using a for loop, and i want when i find the specfic Product Id equal to the Same Product (if clause), and when i find it i use that position to update my list
for (int i = 0; i < adapterItensDoCarrinho.getCount(); i++) {
Log.d("ENTROU", "ENTROU");
Log.d("ID", String.valueOf(lsvCarrinhoCompras.getId()));
if (produtoSelecionado.getId() == adapterItensDoCarrinho.getItemId(i)) {
Log.d("ENTROU 2", "ENTROU 2");
int novaQte = itemDoCarrinho.getQtdeSelecionada();
novaQte++;
itemDoCarrinho.setNome(produtoSelecionado.getNome());
itemDoCarrinho.setQtdeSelecionada(novaQte);
itemDoCarrinho.setPrecoItemVenda(produtoSelecionado.getPrecoProduto());
adapterItensDoCarrinho.updateItemCarrinho(lsvCarrinhoCompras.getId(), itemDoCarrinho);
break;
}
else {
itemDoCarrinho.setNome(produtoSelecionado.getNome());
itemDoCarrinho.setQtdeSelecionada(qtdeProduto);
itemDoCarrinho.setPrecoItemVenda(produtoSelecionado.getPrecoProduto());
adapterItensDoCarrinho.addItemCarrinho(itemDoCarrinho);
}
}
Hope you understand it!
Your Adapter should be the one to handle this behavior. Write a public method in the Adapter class which allows you to pass in the selected product ID. Whenever the selected product ID changes in your Activity/Fragment/whatever, call the public method in the Adapter to update the product ID value. Then, in the getView() method of the Adapter, if the ID matches, perform whatever special behavior you want to have happen for the product with that ID.
I am trying to save the state of checkboxes in my main activity rather than in my custom adapter. I have checked that the correct data is being stored in the sharedprefs and can retrieve the information successfully but when I try and mark the checkboxes on opening the app the viewholder is null. In theory I understand what the problem is but I have no clue how to fix it.
Here is the part of code from the main activity I am having issues with:
for (int i= 0; i<results.size(); i++) {
result = (Results) customAdapter.getItem(i);
if (result != null) {
String RESULT = result.getTitle();
if (sharedPref.getBoolean(result.getTitle(), false)){
Log.i("Saved", result.getTitle());
CustomAdapter.ViewHolder viewHolder = (CustomAdapter.ViewHolder) listView.getTag(i);
Log.i("viewHolder", String.valueOf(viewHolder));
viewHolder.getCheckBox().setChecked(sharedPref.getBoolean(RESULT, false));
}
}
}
You are preparing a List<Results> to pass to adapter right? First add a extra boolean variable in Results model class to represent the state of checkbox. Now at the time you prepare the list in activity, set the value of this new boolean for each item from the preference. So that your List<Results> contain state of the checkbox.
Is there a way to check if a ComboBox has any items in it or whether it is empty? I have an array of ComboBoxes and I need to go through each of them, if there are no items in the ComboBox, then I must hide it. This following code doesn't seem to work:
for (ComboBox cmb : comboBoxes) {
if (cmb.getItems().isEmpty()) {
cmb.hide();
}
}
The code for checking, if the ComboBox has no items is correct, you code for hiding the ComboBoxes is incorrect however.
ComboBox.hide only closes the popup showing the items, if it's open. It does not hide the ComboBox. To hide the ComboBox, you need to set the visibility:
for (ComboBox cmb : comboBoxes) {
if (cmb.getItems().isEmpty()) {
cmb.setVisible(false);
}
}
Alternatively to call a method to hide the ComboBoxes, you can bind the visibleProperty of the ComboBoxes to their own itemsProperty with a custom binding:
List<ComboBox<String>> comboBoxes = new ArrayList<>();
for(int i = 0; i< 10; i++) {
ComboBox<String> combo = new ComboBox<>();
combo.visibleProperty().bind(Bindings.createBooleanBinding(() -> !combo.getItems().isEmpty(),
combo.itemsProperty().get()));
comboBoxes.add(combo);
}
The advantage is, that you don't have to call any methods to hide your ComboBoxes, because the binding is evaluated automatically, therefore no one can see your empty combos.
The .getItems() method returns an ObservableList<T> so you can just check its .size(). This will tell you if it's empty.
for (ComboBox cmb : comboBoxes) {
if (cmb.getItems().size() <= 0) { // or cmb.getItems().isEmpty()
cmb.setVisible(false); }
}
If the ComboBox is populated by a List of its own, you could also just check if the list is empty with the same .size() call.
I am trying to allow my user to search through a table of information, dynamically hiding/showing results that contain the search. I have the hiding part down, and it works well, but I'm having trouble showing the table item again once the search criteria is changed.
Here is my hide code:
searchField.addModifyListener(new ModifyListener() {
#Override
public void modifyText(ModifyEvent arg0) {
modified = true;
for (int i = 0; i < table.getItems().length; i++) {
if (!(table.getItem(i).getText(2)
.contains(searchField.getText()))) {
table.getItem(i).dispose();
}
}
if ("".equals(searchField.getText())) {
modified = false;
//where I would want to un-hide items
}
}
});
Looking at your code, it seems you try to hide the item by calling dispose(). If you dispose a widget, it is gone for good. You cannot get it back.
If you want to unhide it again, will have to create a new item at the position of the previously hidden one with the same content.
Isn't it better to actually operate with some kind of a table model and JFace bindings, rather, then do it like that? And yes, disposing is not hiding. You should probably remove the item from the table.
You have probably to save the data from TableItem into collection before you call dispose. Then when you search again you could check that collection and if matches are found, then insert back into Table by creating new TableItem.
How can I retrieve the View at the position X in a ListView? I dont want to inflate a new one, just retrieve the cell visible in the screen for change some parameters programmatically
Since views in ListView are re-used/re-cycled. There is no direct way of getting a view reference from the ListView.
If you want to access a view you need to extend ArrayAdapter and then override getView. There you should call the super.getView and write your own custom code.
If we you really need to control more than try extending BaseAdapter or CursorAdapter.
Found a dirty solution:
You should be able of identify each row generated. For example adding a TextView with visibility=gone and writing a unique value there when generating (or recycling the row)
In the listactivity call to getListView.setSelection(position) to the desired cell
Survey the listview list for the row (until displayed)
lv=getListView();
for (int i=0;i <lv.getChildCount();i++){
if (((TextView)lv.findViewById(R.id.my_hidden_textview)).getText.equals(mykey)){
// view found
} else {
// schedule another survey "soon"
}
}
For the schedule you can use something like:
final int RETRY_DELAY=100;
new Handler(){
public void handleMessage(Message msg){
if (msg.what<0) return; //something went wrong and retries expired
lv=getListView();
for (int i=0;i <lv.getChildCount();i++){
if (((TextView)lv.findViewById(R.id.my_hidden_textview)).getText.equals(mykey)){
//result = lv.findViewById(R.id.my_hidden_textview);
} else {
this.sendEmptyMessageDelayed(msg.what-1,RETRY_DELAY);
}
}
}
}.sendEmptyMessageDelayed(10,RETRY_DELAY);
As I said is a very ugly solution but it works
I didn't clearly understand your problem. But to what I've understood I would suggest you use a frame layout within a linear layout. You can use another frame layout to do your manipulations.