Im trying to make my listview update the colour of the "android.R.id.text1" line (top line of the two listview lines) whenever you click the "Enrollment" button. The class also calls colourCodeCourses() on create and that works fine to correctly display the course colours, however when I click the enrollment button no matter what I've tried I can't get my listview to update the colour of the text until I hit "back" and reopen the Activities view. At that point, the listview appears in the correct colour. (These aren't all the methods and instance variables, just the relevant ones). Any help is appreciated.
private ListView listView;
private ArrayAdapter<Course> courseArrayAdapter;
private AccessEnrollment accessEnroll;
private ArrayList<Course> comparisonList;
private Degree degree;
public void buttonEnrollOnClick(View v){
int position = listView.getCheckedItemPosition();
Course course = (Course)listView.getItemAtPosition(position);
TextView courseID = (TextView)listView.findViewById(android.R.id.text1);
TextView courseName = (TextView)listView.findViewById(android.R.id.text2);
accessEnroll.insertEnrollmentData(course);
degree.addCourse(course);
colourCodeCourses(position, courseID, courseName, true);
courseArrayAdapter.notifyDataSetChanged();
}
private void colourCodeCourses(int position, TextView courseTitle, TextView courseDescription, boolean newEnroll) {
displayGrade = "";
if(!newEnroll){
if (degree.getCourse(position).getGrade()!="N")
{
displayGrade = " {" + degree.getCourse(position).getGrade() + "} ";
}
courseTitle.setText(degree.getCourse(position).getCourseID()+ " " + displayGrade );
courseDescription.setText(degree.getCourse(position).getCourseName());
if (comparisonList.contains(degree.getCourse(position)))
{
if (degree.getCourse(position).getGrade().equals("IP")){
courseTitle.setTextColor(Color.rgb(0,0,160));
}else{
courseTitle.setTextColor(Color.rgb(0, 160, 0));
}
}
else
{
courseTitle.setTextColor(Color.rgb(160, 0, 0));
}
}else{
courseTitle.setTextColor(Color.BLUE);
}
}
You have to set your styles in ListView Adapter's getView() method.
As far as I can see now you are just searching for a TextView inside a ListView and set its text color.
You should store selected state in your Adapter and set the color of your TextView's accordingly.
Here is the link to go: http://www.vogella.com/tutorials/AndroidListView/article.html
Related
I am working on a Learning app, it has a Tabview so I'm working with Fragments.
The last fragment has buttons on top to navigate through the multiple levels. Below that there is a Recyclerview which contains a Cardview with a Question on the left and an Edittext on the right to answer.
Currently the IME Option is actionSend and I want to not only skip to the next Edittext but also evaluate the Answer that was given. I achieved this already by implementing an OnClickListener but it's quite annoying having to click each Cardview in the Recyclerview to get Feedback, so I want to copy it to the setOnEditorActionListener function for the Editext. The problem I have is that I don't know how to get the position of the current Cardview item (to evaluate the givenAnswer with the corresponding item in the Questionlist) in the Recyclerview without actually clicking it just by changing the Editext.
private RecyclerView myrecyclerview;
private ArrayList<Question> QuestionList;
private QuestionAdapter recyclerAdapter;
private EditText givenAnswer;
public void ClickManager(final ArrayList<Question> list){
//works perfectly when the item is clicked
recyclerAdapter.setOnItemClickListener(new QuestionAdapter.OnItemClickListener() {
#Override
public void onItemClick(final int position) {
View itemView = myrecyclerview.getLayoutManager().findViewByPosition(position);
final EditText givenAnswer = itemView.findViewById(R.id.answer);
ClickEvaluation(list,givenAnswer,position);
}
});
givenAnswer.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
boolean handled = false;
if (i == EditorInfo.IME_ACTION_SEND){
ClickEvaluation(list,givenAnswer,position); //can't access any position
handled = true;
}
return handled;
}
});
}
The evaluation function:
public void ClickEvaluation(final ArrayList<Question> list, EditText givenAnswer, int position){
Question currenQuestion = list.get(position);
if (currenQuestion.correct(givenAnswer.getText().toString())){
currenQuestion.gaveCorrectAnswer();
score += 1;
current.setText(String.format("%d",score));
}else{
currenQuestion.showCorrectAnswer();
}
givenAnswer.setText("");
recyclerAdapter.notifyItemChanged(position);
}
Thanks a lot in advance!
I have the following code for the recyclerview adapter for an android app that I'm working on right now:
#Override
public void onBindViewHolder(final FeedViewHolder contactViewHolder, final int i) {
final FeedInfo ci = feedInfoList.get(i);
//Set the text of the feed with your data
contactViewHolder.feedText.setText(ci.getFeed());
contactViewHolder.surNameText.setText(ci.getSurName());
contactViewHolder.nameText.setText(ci.getFirstName());
contactViewHolder.feedDate.setText(ci.getDate());
contactViewHolder.numberOfGoingText.setText(ci.getNumber_of_going());
contactViewHolder.numberOfInterestedText.setText(ci.getNumber_of_interested());
//seteaza fotografia de profil in postare
new ProfilePictureDownloadImage(contactViewHolder.profilePicture).execute(ci.getProfileImageURL());
ImageButton interestedButton = contactViewHolder.interestedButton;
interestedButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = i;
FeedInfo fi = feedInfoList.get(position);
int displayedNumberOfInterested = Integer.parseInt(ci.getNumber_of_interested()) + 1;
contactViewHolder.numberOfInterestedText.setText(Integer.toString(displayedNumberOfInterested));
System.out.println("emilutzy interested from within" + fi.getPostID());
contactViewHolder.surNameText.setText("kk");
}
});
}
The problem is the click listener. In theory the button I press should increment the number right next to it. However, since I have to declare onBindViewHolder's arguments as final, only the first click works, the rest of the clicks do not change the value of the number. I am new to Android, so could you please help me find a better solution?
There's a nice method called getAdapterPosition() that you can use in your RecyclerView's ViewHolder.
Instead of setting the click listener in onBindViewHolder, set it in the constructor of your ViewHolder like so:
public class FeedViewHolder extends RecyclerView.ViewHolder {
private TextView feedText;
private TextView surNameText;
private Button interestedButton;
// ... the rest of your viewholder elements
public FeedViewHolder(View itemView) {
super(itemView);
feedtext = itemView.findViewById(R.id.feedtext);
// ... find your other views
interestedButton.setOnClickListener(new View.OnClickListener() {
final FeedInfo fi = feedInfoList.get(getAdapterPosition());
int numInterested = Integer.parseInt(ci.getNumber_of_interested()) + 1;
// setting the views here might work,
// but you will find that they reset themselves
// after you scroll up and down (views get recycled).
// find a way to update feedInfoList,
// I like to use EventBus to send an event to the
// host activity/fragment like so:
EventBus.getDefault().post(
new UpdateFeedInfoListEvent(getAdapterPosition(), numInterested));
// in your host activity/fragment,
// update the list and call
// notifyDatasetChanged/notifyDataUpdated()
//on this RecyclerView adapter accordingly
});
}
}
Don't set your position in onBindViewHolder to final (Android Studio will warn you why).
I'm not sure how the object FeedInfo looks like but you could also at a method called for example increaseNumberOfInterested() which would increase the value of Number_of_interested by one and would persist in the object when the recyclerview recycle the cell. it would like kind of like below
#Override
public void onBindViewHolder(final FeedViewHolder contactViewHolder, final int i) {
final FeedInfo ci = feedInfoList.get(i);
//Set the text of the feed with your data
contactViewHolder.numberOfInterestedText.setText(ci.getNumber_of_interested());
contactViewHolder.interestedButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Increase the number of interested in the object, so it can be persisted when cell is reclycled
ci.setNumberOfInterested(ci.getNumber_of_interested()) + 1);
//Get new value and display
contactViewHolder.numberOfInterestedText.setText(Integer.toString(ci.getNumber_of_interested()));
}
I want to display a ListView where each row represents the answer to a question. When the user presses the button CHECK I want the rows of the ListView to change color according to the result (if the answer was wrong, correct, not selected and so on...).
In my onCreateView() I'm creating the following CursorAdapter:
Cursor crs = db.queryQuestionAnswers(questionID); // a cursor with all answers relative to the question
adapter = new CursorAdapter(getActivity(), crs, 0) {
#Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
return ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.listfragment_test_row, listview, false); // Row of the listview
}
// Instance items of each row
#Override
public void bindView(View view, Context context, Cursor crs) {
Answer answer = test.getQuestion(current_question).getAnswer(crs.getPosition());
TextView answerTv = (TextView) view.findViewById(R.id.ans_test_button);
answerTv.setText(answer.getText());
view.setOnClickListener(new AnswerOnClickListener(answer));
if (show_solution) { // User has clicked "CHECK"
displayResult(view, answer); // Color answers according to selection and correctness
} else
view.setBackgroundColor(Color.TRANSPARENT); // The question has just been displayed
}
#Override
public long getItemId(int position) {
Cursor cursorAdapter = adapter.getCursor();
cursorAdapter.moveToPosition(position);
return cursorAdapter.getLong(cursorAdapter.getColumnIndex(DatabaseStrings.FIELD_ID));
}
};
Whenever the user presses the CHECK button so (bringing show_solution to true), the app should check the following fields and act on the relative view accordingly:
private void displayResult(View view, Answer answer) {
view.setEnabled(false);
if (answer.isSolution() && answer.isChoice()) // User selected a correct answer
view.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.colorLightGreen));
else if (answer.isChoice()) // User selected a wrong answer
view.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.colorMediumRed));
else if (answer.isSolution()) // User didn't select a solution
view.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.colorLightBlue));
else { // Answer was nor selected nor solution
// [...] Hide view with an animation [..]
}
}
}
But in all cases the last answer gets colored (apparently with a random color) and then vanishes (as it was nor selected nor solution).
It looks like for only the last row the program enters in all if statements.
The only case when it works as it was supposed to, is when the user selects all answers: correct ones are colored green and wrong one red... while no answer vanishes. Not even the last one.
I managed to fix the problem relative to the color adding the following line inside the last else statement.
view.setBackgroundColor(Color.TRANSPARENT);
But the last line keep vanishing. What's wrong?
EDIT:
Here's the AnswerOnClickListener implementation:
// Listener for answer selection
public class AnswerOnClickListener implements View.OnClickListener {
Answer answer;
private AnswerOnClickListener(Answer answer) { this.answer = answer; }
#Override
public void onClick(View v) {
answer.changeChoice();
if (answer.isChoice()) { // Answer has been selected by the user
v.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.colorLightYellow));
} else { // Answer has been deselected by the user
v.setBackgroundColor(Color.TRANSPARENT);
}
}
}
My program displays a horizontally sliding row of buttons containing the text description of a work of art. When a button is clicked, ImageActivity launches to display the corresponding work of art. When I click on any of the text buttons, though, it always displays the very last painting in the Array.
I'm trying to pass an int ID to a second activity so that it will display the correct painting once it's corresponding description is clicked.
Thank you!
Here's my MainActivity:
import android.content.Intent;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
public class MainActivity extends Activity {
//CONTAINING PAINTINGS
private LinearLayout mLinearList;
private String id;
private Painting painting;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
//REFERENCE THE SCROLLABLE LAYOUT STRUCTURE IN MAIN_SCREEN.XML
mLinearList = (LinearLayout) findViewById(R.id.linearList);
//FILL THE SCROLLABLE LAYOUT STRUCTURE WITH PAINTINGS
fillTextCarousel();
}
private void fillTextCarousel() {
// POPULATE THE LINEAR LIST CAROUSEL WITH PAINTINGS AND DESCRIPTIONS
Button buttonItem;
for (int i = 0; i < RenaissanceDatabase.description.length; i++) {
//STORE THE INDIVIDUAL PAINTINGS AS BUTTONS
buttonItem = new Button(this);
painting = new Painting(RenaissanceDatabase.description[i], RenaissanceDatabase.id[i]);
//USE THE CONTENT DESCRIPTION PROPERTY TO STORE
//PAINTING DATA
buttonItem.setContentDescription(painting.getDescription());
buttonItem.setText(painting.getDescription());
//SET AN ONCLICK LISTENER FOR THE TEXT BUTTON
buttonItem.setOnClickListener(displayPainting);
//ADD THE IMAGE BUTTON TO THE SCROLLABLE LINEAR LIST
mLinearList.addView(buttonItem);
}
}
private View.OnClickListener displayPainting = new View.OnClickListener() {
public void onClick(View btn) {
// COLLECT THE IMAGE STORED FOR THE PAINTING
//String Painting_ID = Integer.toString(painting.getId());
Intent imgIntent = new Intent(getApplicationContext(), ImageActivity.class);
imgIntent.setAction(imgIntent.ACTION_SEND);
imgIntent.putExtra("image_id", painting.getId());
startActivity(imgIntent);
}
};
My ImageActivity that I am trying to pass an integer ID to:
public class ImageActivity extends Activity {
private Painting painting;
private int index;
private int[] IDs;
private String[] Desc;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
Intent objIntent = getIntent();
int ID_Val = objIntent.getIntExtra("image_id", 0);
ImageView art = (ImageView) findViewById(R.id.imageView2);
art.setImageResource(ID_Val);
}
}
And the painting database, which I'm taking taking the ID from:
public class RenaissanceDatabase {
public static String description[] = {
"Venus of Urbino\nTitan, 1538",
"St. John the Baptist\nLeonardo da Vinci, 1516",
"Protrait of Baldassare Castiglione\nRaphael, 1515",
"The Entombent of Christ\nCaravaggio, 1603",
"Coronation of the Virgin\nFra Angelico, 1435",
"Mars and Venus\n Sandro Bottcelli, 1483"};
public static int id[] = {
R.drawable.painting1, // VENUS OF URBINO
R.drawable.painting2, // ST.JOHN BAPTIST
R.drawable.painting3, // BALDASSARE
R.drawable.painting4, // ENTOMBENT OF CHRIST
R.drawable.painting5, // CORONOATION
R.drawable.painting6 // MARS AND VENUS
};
}
Set the id for every button in your for loop -
for (int i = 0; i < RenaissanceDatabase.description.length; i++) {
//STORE THE INDIVIDUAL PAINTINGS AS BUTTONS
buttonItem = new Button(this);
painting = new Painting(RenaissanceDatabase.description[i], RenaissanceDatabase.id[i]);
//USE THE CONTENT DESCRIPTION PROPERTY TO STORE
//PAINTING DATA
buttonItem.setId(painting.getId());
....
}
}
And then change your OnClickListener -
private View.OnClickListener displayPainting = new View.OnClickListener() {
public void onClick(View btn) {
....
imgIntent.putExtra("image_id", btn.getId());
startActivity(imgIntent);
}
};
The way your code is set up this makes perfect sense.
Look at the loop you're using to configure everything.
for (int i = 0; i < RenaissanceDatabase.description.length; i++) {
.....
painting = new Painting(RenaissanceDatabase.description[i], RenaissanceDatabase.id[i]);
...
}
What is the value of painting at the end of this loop? It's whatever was in the last position in the array.
Now look at your code to pass the ID:
private View.OnClickListener displayPainting = new View.OnClickListener() {
public void onClick(View btn) {
....
imgIntent.putExtra("image_id", painting.getId());
.....
}
};
The code presented never updates the "current painting" to the one which was touched. You need to figure out which painting the user has touched, and use the ID of that painting.
Another answer has a recommendation to set the buttonId to the id of the painting - this has some issues so I wouldn't personally recommend that.
Instead I would use an Adapter and ViewHolder pattern and leverage the viewholder to contain this meta data. This is a much more scalable solution.
I have a EditText box in which i want to control the cursor and modify the text programmatically
I have 12 button keypad made using 12 buttons in a GridView. With each button press I have a specific text which is to be inserted in EditText box at cursor position. For this i need cursor position so that i can insert the my custom text in the EditText view
I have two buttons for moving cursor position left/right by one character. Alternatively the cursor can also be set by touching EditText view (as EditText is supposed to behave)
Also i want the current position of cursor in EditText whenever Cursor position changes (I think i have to implement some kind of interface but i dont know how)
What i have tried so far
I am storing the key presses in an ArrayList<String>
I am setting the edittext.setText(String) everytime a key is pressed
can get the editable text through getText() but setText() only accepts strings.
Hence i am confused. What should i do to fulfill all my requirements.
PS: I am a Android beginner, and am making my 2nd app (which is a scientific calculator if it helps)
also if anyone volunteers to review my code, I'll be deeply obliged to him
I dont know why you need the cursor position of the textview but take a look at this question here : Get Cursor Position in Android in Edit Text?
Actually you can edit the text in the textview on code by getting the input or if you want you can implement the TextWatcher interface to know what every input the user type in your textview like this one:
private class CheckText implements TextWatcher {
#Override
public void afterTextChanged(Editable s) {
//triggers after the user changed the input on text
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
//triggers before the user changed the input on text
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
//triggers when the user changed the input on text
}
}
To set any number in EditText use Wrapper class then set it on EditText using toString().
For set position you can use editText.setSelection(position);
It is how I did something similar
Stored id of all the button in a array as shown below.
int[] kbdButtons = { R.id.button1, R.id.button2, R.id.button3,
R.id.button4, R.id.button5, R.id.button6, R.id.button7,
R.id.button8, R.id.button9, R.id.button10, R.id.button11,
R.id.button12, R.id.button13, R.id.button14, R.id.button15}
2.Then added custom Onclicklistner to all buttons in the kbdButtons array
for (int i = 0; i < kbdButtons.length; i++) {
Button buttonNum = (Button) dialoglayout
.findViewById(kbdButtons[i]);
buttonNum.setOnClickListener(hindiKbdBtnsClick);
}
and here is the declaration of custom clicklistner
private OnClickListener hindiKbdBtnsClick = new OnClickListener() {
#Override
public void onClick(View v) {
int btnId = v.getId();
if (isShift && btnId != R.id.kbdKeyLeftShift
&& btnId != R.id.kbdKeyRightShift) {
sNotPressedView.setVisibility(View.VISIBLE);
sPressedView.setVisibility(View.GONE);
isShift = false;
}
if (btnId == R.id.kbdKeyLeftShift || btnId == R.id.kbdKeyRightShift) {
if (!isShift) {
sNotPressedView.setVisibility(View.GONE);
sPressedView.setVisibility(View.VISIBLE);
isShift = true;
} else {
sNotPressedView.setVisibility(View.VISIBLE);
sPressedView.setVisibility(View.GONE);
isShift = false;
}
} else if (btnId == R.id.kbdKeySpace || btnId == R.id.kbdKeyEnter) {
hkEditText.append(" ");
} else if (btnId == R.id.kbdKeyBackSpace) {
String txt_curr_val = hkEditText.getText().toString();
if (txt_curr_val.length() != 0)
txt_curr_val = txt_curr_val.substring(0,
txt_curr_val.length() - 1);
hkEditText.setText(txt_curr_val);
hkEditText.setSelection(txt_curr_val.length());
}else if (btnId == R.id.kbdKeyHide) {
mDialog.hide();
}else {
Button b = (Button) v;
String btnText = b.getText().toString();
hkEditText.append(btnText);
}
}
};
Explanation - hkEditText is my editText view i.e.
EditText hkEditText = (EditText)FindViewById(R.id.myEdittextId);
-see I just appended the text written on the button that is pressed at that time.
-you can also see the functionality of some special buttons like space, shift and enter