Only 1 button enable in ListView, custom adapter - android-listview

I run into a problem where I need to enable my button in the ListView. The weird thing is :
public class CookingStepAdapter extends ArrayAdapter<CookingStep> {
...
private void addButtonToList(Button clock, Button skip){
if (list_clock_button == null) {
list_clock_button = new ArrayList<Button>();
iterate = 0;
}
if (list_skip_button == null)
list_skip_button = new ArrayList<Button>();
list_clock_button.add(clock);
list_skip_button.add(skip);
clock.setEnabled(true);
skip.setEnabled(true);
list_clock_button.get(0).setEnabled(true);
list_clock_button.get(0).setFocusable(true);
list_clock_button.get(0).setFocusableInTouchMode(true);
list_clock_button.get(0).invalidate();
list_skip_button.get(0).setEnabled(true);
list_skip_button.get(0).setFocusable(true);
list_skip_button.get(0).setFocusableInTouchMode(true);
list_skip_button.get(0).postInvalidate();
}
}
When I set enable with the list_clock_button.get(0), it's not working at all. But clock.setEnabled(true); actually worked.
But then I only want the first button of the ListView enabled, that makes the first option more fit in this situation. The second option works, but it made all the buttons enabled, that's not what I want. I did recheck the first button address, and it matched list_clock_button.get(0), why it's not working.
EDIT :
Here's my function getView :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.cooking_steps_and_timer, parent, false);
final Button button = (Button) rowView.findViewById(R.id.button_timer);
final TextView timer = (TextView) rowView.findViewById(R.id.cooking_timer);
final Button skipButton = (Button) rowView.findViewById(R.id.button_skip);
TextView stepContent = (TextView) rowView.findViewById(R.id.cooking_step_content);
final CookingStep step = list.get(position);
String stepOrder = (String) context.getResources().getText(R.string.step_order) + " " + step.getOrder();
String content = "<b>" + stepOrder + ":</b>" + " " + step.getContent() + "\n";
stepContent.setText(Html.fromHtml(content));
if (step.getTimer() == null || step.getTimer() == 0){
timer.setVisibility(View.GONE);
button.setVisibility(View.GONE);
skipButton.setVisibility(View.GONE);
} else {
//myTimer = new CookingTimer(step.getTimer());
timer.setText(step.getMyTimer().toString());
step.setCountDown(new CountDownTimer(step.getTimer() * 60000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
step.getMyTimer().tick();
timer.setText(step.getMyTimer().toString());
}
#Override
public void onFinish() {
nextButtonEnable();
}
});
button.setText(R.string.button_available);
skipButton.setText(R.string.skip_button_content);
addButtonToList(button, skipButton);
//button.setEnabled(true);
list_clock_button.get(0).setEnabled(true);
button.requestFocusFromTouch();
button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (!button.isPressed()) {
button.setPressed(true);
button.setText(R.string.button_available);
step.getCountDown().start();
} else {
button.setPressed(false);
button.setText(R.string.button_pressed);
step.getCountDown().cancel();
}
}
return true;
}
});
skipButton.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
step.getCountDown().cancel();
nextButtonEnable();
}
return true;
}
});
}
return rowView;
}

The reason of all buttons getting enabled is you are setting all of them enable yourself. To set any particular button enable you have to check the id or the item position to set that particular button to enable.
Like this for example:-
if(clock.getID == R.id.some_id_in_xml){
clock.setEnabled(true);
}
But before that you have to check the position of the item to select the desired item in the list.

Related

How to realize strikethrough text in Listview with CheckBox?

I have a ListView with CheckBox and TextView. But when I click on Checkbox, I can’t get strikethrough text. But when I click on the last checkbox, I get strikethrough text.
This is my GetView:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder listViewHolder;
if(convertView == null){
listViewHolder = new ViewHolder();
convertView = lInflater.inflate(R.layout.listview_with_checkbox, parent, false);
listViewHolder.textInListView = (TextView)convertView.findViewById(R.id.textView);
listViewHolder.checkBox = (CheckBox)convertView.findViewById(R.id.checkBox);
convertView.setTag(listViewHolder);
}else{
listViewHolder = (ViewHolder)convertView.getTag();
}
listViewHolder.textInListView.setText(listStorage.get(position).getName());
listViewHolder.checkBox.setChecked(false);
listViewHolder.checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listViewHolder.checkBox.isChecked()){
listViewHolder.textInListView.setPaintFlags(listViewHolder.textInListView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
listViewHolder.checkBox.setChecked(true);
}else{
listViewHolder.checkBox.setChecked(false);
}
}
});
return convertView;
}
This is my Main:
ListView listViewWithCheckBox = (ListView)RootView1.findViewById(R.id.listView);
List<AimsDiaryCheckBoxBolvanka> listViewItems = new ArrayList<AimsDiaryCheckBoxBolvanka>();
listViewItems.add(new AimsDiaryCheckBoxBolvanka("Nigeria"));
listViewItems.add(new AimsDiaryCheckBoxBolvanka("Ghana"));
listViewItems.add(new AimsDiaryCheckBoxBolvanka("Senegal"));
listViewItems.add(new AimsDiaryCheckBoxBolvanka("OPA"));
listViewItems.add(new AimsDiaryCheckBoxBolvanka("KNIGA"));
listViewWithCheckBox.setAdapter(new AimsDiaryCheckBoxAdapter(getContext(), listViewItems));
listViewWithCheckBox.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// make Toast when click
Toast.makeText(getActivity().getApplicationContext(), "Position " + position, Toast.LENGTH_LONG).show();
}
});
I believe it has something to do with these lines:
if (listViewHolder.checkBox.isChecked()){
listViewHolder.textInListView.setPaintFlags(listViewHolder.textInListView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
listViewHolder.checkBox.setChecked(true);
Take a look at what listViewHolder is pointing to and you are doing the isChecked() before actually calling listViewHolder.checkBox.setChecked(true). Looks like a timing issue

JavaFX custom ListCell

I'm trying to animate ListCell when they appear.
Specially I try to animate a new cell when it was just added to the list.
For now it's working pretty OK except when I scroll the ListView, then indexes get messed up and the wrong cell is animated.
I use a boolean flag (entering) in my item model to detect when a cell is used for a brand new item.
public class TimeListCell extends ListCell<MarkItem> {
private static final String BUTTON_GOTO_MARK_CLASS = "but-markgoto";
private static final String LABEL_TIME_MARK_CLASS = "track-time";
private static final String BUTTON_DELETE_MARK_CLASS = "but-markdel";
private static final String MARK_HIGHLIGHT_CURRENT_CLASS = "highlighted";
private Instant time;
private MarkItem markItem;
protected ListCellAnimation anim;
private HBox root = new HBox();
private Button go = new Button();
private Label track = new Label();;
private Button del = new Button();
private ChangeListener<? super Boolean> highlightChange = (e, o, n) -> { setHighlighted(n); };
public TimeListCell (Consumer<MarkItem> onGoto, Consumer<MarkItem> onDelete) {
root.setAlignment(Pos.CENTER);
go.getStyleClass().add(BUTTON_GOTO_MARK_CLASS);
go.setOnAction( e -> {
if (onGoto != null) {
// Trigger GOTO consumer function
onGoto.accept(markItem);
}
});
track.getStyleClass().add(LABEL_TIME_MARK_CLASS);
del.getStyleClass().add(BUTTON_DELETE_MARK_CLASS);
del.setOnAction( e -> {
// First trigger exit animation then delete item
this.animateExit(onDelete);
});
root.getChildren().add(go);
root.getChildren().add(track);
root.getChildren().add(del);
}
#Override
protected void updateItem (final MarkItem item, boolean empty) {
super.updateItem(item, empty);
if (markItem != null) {
markItem.highlightedProperty().removeListener(highlightChange);
}
if (!empty && item != null) {
markItem = item;
time = item.getTime();
track.setText(DateUtil.format(time, DateUtil.Pattern.TIME));
setGraphic(root);
item.highlightedProperty().addListener(highlightChange);
setHighlighted(item.isHighlighted());
if (anim == null) {
//Adding Animation to the ListCell
anim = new ListCellAnimation(this);
//KeyFrame[] f = getKeyFrames(types);
KeyFrame[] frames = null;
if (anim.getKeyFrames().size() == 0) {
KeyFrame[] f = anim.getPopIn(frames);
if (f != null) {
anim.getKeyFrames().addAll(f);
}
}
}
if (item.isEntering()) {
//Checking when to play Animation
animateEnter();
item.setEntering(false);
}
} else {
setGraphic(null);
}
}
/**
* Set/unset cell highlighted style for display.
*
* #param highlighted
* Whether or not to highlight the cell
*/
public void setHighlighted (boolean highlighted) {
track.getStyleClass().remove(MARK_HIGHLIGHT_CURRENT_CLASS);
if (highlighted)
track.getStyleClass().add(MARK_HIGHLIGHT_CURRENT_CLASS);
}
/**
* Animate entering cell.
*/
private void animateEnter() {
if (anim != null && anim.getKeyFrames().size() >= 0
&& (anim.getTimeline().getStatus() == Timeline.Status.STOPPED
|| anim.getTimeline().getStatus() == Timeline.Status.PAUSED)) {
anim.getTimeline().playFromStart();
}
}
/**
* Animate exiting cell.
* Trigger DELETE consumer function when animation is complete.
*/
private void animateExit (Consumer<MarkItem> onDelete) {
anim.getReversedTimeline().setOnFinished( t -> {
// Remove item from list
if (onDelete != null) {
onDelete.accept(markItem);
}
// Prepare cell for next item to use it
scaleXProperty().set(1);
scaleYProperty().set(1);
});
anim.getReversedTimeline().playFromStart();
}
public Instant getTime () {
return time;
}
}
Has anyone any idea of what could mess up the cell indexing ?
Thanks.
If a cell which is animating is reused to display an item that is not "entering", then you need to stop the current animation:
if (item.isEntering()) {
//Checking when to play Animation
animateEnter();
item.setEntering(false);
} else {
anim.getTimeline().stop();
}
In general, you seem to be assuming that any given cell is only ever used for a single item, which is certainly not the case. There may be other bugs in your code that are consequences of this assumption, but this is the main one I can see.

GWT Cell Table Clicking on a new row gives value of Previously selected row

In GWT 2.6 CellTable, I'm writing a single click event to perform some operation. I can not get the correct Row Index while clicking on the CellTable Row; only a double click event returns the row correctly.
final SingleSelectionModel<PatientDTO> selectionModel =
new SingleSelectionModel<PatientDTO>();
patientsTable.setSelectionModel(selectionModel);
patientsTable.addDomHandler(new ClickHandler()
{
#Override
public void onClick(ClickEvent event)
{
PatientDTO selected = selectionModel.getSelectedObject();
if (selected != null)
{
RootLayoutPanel.get().clear();
RootLayoutPanel.get().add(new PatientPanel(selected));
}
}
}, ClickEvent.getType());
Either use SingleSelectionModel or MultiSelectionModel and add SelectionChangeHandler on it that will be fired when selection is changed in the CellTable
Sample code:
final SingleSelectionModel<Contact> selectionModel = new SingleSelectionModel<Contact>();
//final MultiSelectionModel<Contact> selectionModel = new MultiSelectionModel<Contact>();
selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
#Override
public void onSelectionChange(SelectionChangeEvent event) {
Set<Contact> selected = selectionModel.getSelectedSet();
if (selected != null) {
for (Contact contact : selected) {
System.out.println("You selected: " + contact.name);
}
}
}
});
OR alternatively try with CellPreviewHandler
table.addCellPreviewHandler(new Handler<Contact>() {
#Override
public void onCellPreview(CellPreviewEvent<Contact> event) {
int row = event.getIndex();
int column = event.getColumn();
if ("focus".equals(event.getNativeEvent().getType())) {
//..
}
if ("blur".equals(event.getNativeEvent().getType())) {
//...
}
if ("mousedown".equals(event.getNativeEvent().getType())) {
//..
}
if ("mouseover".equals(event.getNativeEvent().getType())) {
//..
}
}
});

how can I edit the value of a textview inside the listview through edittext which is also inside the listview?

Here is my code. I have a textview and edittext inside the listview, can anyone help me with this? Thanks in advance....
final ListAdapter adapter = new SimpleAdapter(Viewer.this, viewnotes,
R.layout.note_list, new String[] { "Id", "Notes", "Notes" },
new int[] { R.id.noteid, R.id.listnote2, R.id.listnote });
listnote.setAdapter(adapter);
listnote.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
EditText textnote = (EditText) view.findViewById(R.id.listnote2);
notename1 = (TextView) findViewById(R.id.listnote);
textnote.setVisibility(View.VISIBLE);
notename1.setVisibility(View.GONE);
}
});
}
Handle the softkeybord done or enter like this and refresh the list
editText.setOnEditorActionListener(new TextView.OnEditorActionListener(){
public boolean onEditorAction(TextView exampleView, int actionId, KeyEvent event){
if(actionId == EditorInfo.IME_ACTION_DONE
|| actionId == EditorInfo.IME_NULL
|| event.getKeyCode() == KeyEvent.KEYCODE_ENTER){
//Do something in here
return true;
} else {
return false;
}
}
});

How to set the color of the first column of a Listview item?

I have a Listview (shown in an AlertDialog) that is composed by two columns, made with a HashMap (got the idea somewhere here).
Each column is a TextView. It works well.
Now I want to change the textcolor of the first column of a given row, but I have no idea on how to pick and set this... I googled for hours! Any clues??
This is my code (lists is a SortedSet):
public void showlistdesc () {
ListView listview = new ListView(this);
listview.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
listview.setSoundEffectsEnabled(true);
listview.setSelector(R.drawable.selector);
Integer i=0, pos = 0;
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map;
for (String l : lists) {
if (l.equals(currlist)) pos = i;
i++;
map = new HashMap<String, String>();
map.put("list", l);
map.put("desc", getlistdesc(l, false));
mylist.add(map);
}
listview.setAdapter(new SimpleAdapter(this, mylist, R.layout.lists_row,
new String[] {"list", "desc"}, new int[] {R.id.list1, R.id.desc1}));
AlertDialog.Builder builder = new AlertDialog.Builder(AveActivity.this)
.setView(listview)
.setIcon(R.drawable.ic_launcher)
.setTitle(lists.size() + " bird lists in databases");
final AlertDialog dial = builder.create();
//Scrolls the listview to this position at top
listview.setSelection(pos);
dial.show();
}
Thanks!
EDIT
Tried to extend SimpleAdapter with the following code, and all I can see are solid black rows:
public class MySimpleAdapter extends SimpleAdapter {
private Context context;
public MySimpleAdapter(Context context,List<? extends Map<String, ?>> data,
int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.lists_row, null);
}
TextView list1 = ((TextView) v.findViewById(R.id.list1));
TextView desc1 = ((TextView) v.findViewById(R.id.desc1));
if (v.isPressed()) {
v.setBackgroundColor(context.getResources().getColor(R.color.pressed));
list1.setTypeface(null, 1);
list1.setTextColor(context.getResources().getColor(R.color.selected));
} else {
v.setBackgroundColor(context.getResources().getColor(R.color.black));
if (v.isSelected()) {
list1.setTypeface(null, 1);
list1.setTextColor(context.getResources().getColor(R.color.checked));
desc1.setTextColor(context.getResources().getColor(R.color.white));
} else {
list1.setTypeface(null, 0);
list1.setTextColor(context.getResources().getColor(R.color.normal));
desc1.setTextColor(context.getResources().getColor(R.color.lesswhite));
}
}
return v;
}
}
Now you have special requirement, it is no longer simple, you can't use SimpleAdapter to achieve the effect you are asking. You will have to extend BaseAdapter and in the getView() method you can do the following:
if (position == 0) {
convertView.setBackground(color1);
} else {
convertView.setBackground(color2);
}
Or if what you want is a Header, you can use ListView.addHeaderView() without much hassle.
I found a solution, essentially contained in several posts here.
What I did was to use listview.setItemChecked(pos, true);, something that I tried before and failed, because it showed nothing. The problem was that LinearLayout does not implement Checkable. So I implemented it (code found essentially somewhere here also) with this:
public class CheckableLinearLayout extends LinearLayout implements Checkable {
private boolean isChecked;
public CheckableLinearLayout(Context context) {
super(context);
}
public CheckableLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setChecked(boolean isChecked) {
this.isChecked = isChecked;
TextView list1 = ((TextView) findViewById(R.id.list1));
TextView desc1 = ((TextView) findViewById(R.id.desc1));
if (isPressed()) {
list1.setTextColor(getResources().getColor(R.color.selected));
setBackgroundColor(getResources().getColor(R.color.pressed));
} else {
setBackgroundColor(getResources().getColor(R.color.black));
if (isChecked) {
list1.setTextColor(getResources().getColor(R.color.checked));
desc1.setTextColor(getResources().getColor(R.color.white));
} else {
list1.setTextColor(getResources().getColor(R.color.normal));
desc1.setTextColor(getResources().getColor(R.color.lesswhite));
}
}
}
public boolean isChecked() {
return isChecked;
}
public void toggle() {
setChecked(!isChecked);
}
}
And that's it. No need to use selector, nor to touch the adapter. To make this work, in the row layout, use <com.[yourpackage].CheckableLinearLayout instead of the usual LinearLayout.