Issue in setting Textview's text in Custom Adapter for Android - android

I am not able to set textview's setText property inside getView() method of Custom Adapter.
I already tried below solutions but it does not work for me :
Solution One
Solution Two
Solution Three
Listview.xml file :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/imgLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:divider="#null"
android:dividerHeight="5dp"
android:scrollbars="none" />
</RelativeLayout>
Below is my keep_resing xml file :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/customRowLayout"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_marginTop="20dp"
android:orientation="horizontal" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:orientation="vertical" >
<ImageButton
android:id="#+id/Btn"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:background="#drawable/thumb_down_disabled" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="#string/resing"
android:textColor="#357EC7"
android:textSize="10sp" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:orientation="vertical" >
<TextView
android:id="#+id/lyricsTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<RelativeLayout
android:id="#+id/parentLayout"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="5dp"
android:background="#drawable/playing_view"
android:orientation="horizontal" >
<TextView
android:id="#+id/helloTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="5dp"
android:singleLine="true"
android:text="Hello"
android:textColor="#357EC7"
android:textSize="14sp" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:background="#drawable/volume" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:orientation="vertical" >
<ImageButton
android:id="#+id/keepBtn"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginRight="10dp"
android:background="#drawable/thumb_up_disabled" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="#string/keep"
android:textColor="#357EC7"
android:textSize="10sp" />
</LinearLayout>
</RelativeLayout>
Below is my adapter code :
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.simpleframework.xml.stream.Position;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Handler;
import android.os.PowerManager;
import android.sax.StartElementListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class KeepReSingAdapter extends BaseAdapter implements OnClickListener {
/*********** Declare Used Variables *********/
private Activity activity;
private ArrayList data;
private static LayoutInflater inflater = null;
public Resources res;
SongCue tempValues = null;
int i = 0;
private ArrayList<SongCue> songCue;
private int cueIndex = 0;
private String selectedSongId;
private MediaPlayer mMediaPlayer;
ViewHolder holder;
View vi;
boolean right_button_flag, left_button_flag;
SessionManager session;
// int left_button_flag;
/************* CustomAdapter Constructor *****************/
public KeepReSingAdapter(Activity a, ArrayList d, Resources resLocal) {
/********** Take passed values **********/
activity = a;
data = d;
res = resLocal;
/*********** Layout inflator to call external xml layout () ***********/
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
selectedSongId = SessionManager.getInstance(
activity.getApplicationContext()).getString(
AppConstants.SONG_ID);
right_button_flag = false;
left_button_flag = false;
// Session class instance
session = new SessionManager(activity.getApplicationContext());
}
/******** What is the size of Passed Arraylist Size ************/
public int getCount() {
if (data.size() <= 0)
return 1;
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
/********* Create a holder Class to contain inflated xml file elements *********/
public static class ViewHolder {
public TextView lyricsTxt, helloTxt;
// public TextView text1;
public ImageButton leftBtn, rightBtn;
public RelativeLayout parentLayout;
public LinearLayout rowLayout;
// public TextView textWide;
// ImageView image;
}
/****** Depends upon data size called for each row , Create each ListView row *****/
public View getView(final int position, View convertView, ViewGroup parent) {
vi = convertView;
if (convertView == null) {
vi = inflater.inflate(R.layout.keep_resing, null);
holder = new ViewHolder();
holder.lyricsTxt = (TextView) vi.findViewById(R.id.lyricsTxt);
holder.helloTxt = (TextView) vi.findViewById(R.id.helloTxt);
holder.leftBtn = (ImageButton) vi.findViewById(R.id.reSingBtn);
holder.rightBtn = (ImageButton) vi.findViewById(R.id.keepBtn);
holder.parentLayout = (RelativeLayout) vi
.findViewById(R.id.parentLayout);
holder.rowLayout = (LinearLayout) vi
.findViewById(R.id.customRowLayout);
vi.setTag(holder);
} else {
holder = (ViewHolder) vi.getTag();
}
if (data.size() <= 0) {
} else {
/***** Get each Model object from Arraylist ********/
tempValues = null;
tempValues = (SongCue) data.get(position);
holder.lyricsTxt.setText(tempValues.getLyric());
List<Song> AllSong = SplashScreen_Activity.songs;
if (selectedSongId != null) {
for (Song tempsong : AllSong) {
if (tempsong.songId.equals(selectedSongId)) {
songCue = (ArrayList<SongCue>) tempsong.songCues.songCue;
}
}
} else {
}
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(activity.getApplicationContext(),
" " + position, Toast.LENGTH_SHORT).show();
holder.helloTxt.setText("Test");
Toast.makeText(activity.getApplicationContext(),
holder.helloTxt.getText().toString(),
Toast.LENGTH_LONG).show();
}
});
}
vi.setOnClickListener(new OnItemClickListener(position));
return vi;
}
#Override
public void onClick(View v) {
Log.v("CustomAdapter", "=====Row button clicked=====");
}
/********* Called when Item click in ListView ************/
private class OnItemClickListener implements OnClickListener {
private int mPosition;
OnItemClickListener(int position) {
mPosition = position;
}
#Override
public void onClick(View arg0) {
}
}
}
Problem is, I am not able to change the text view text to "Test".
Note : If I see the value in Toast by doing "holder.helloTxt.getText().toString()" it shows me "Test".
I don't know why this problem is arising.Any help will be highly appreciated.
Thanks

Finally I got the solution to my question and guess what it was a minor updation in the code.
I updated my code to :
final ViewHolder holder;
inside getView() of CustomAdapter instead of declaring it globally.
Once again, thanking you all for your answers.
It helped me to look into my code in detail.

Try this hope this helps
vi = convertView;
if (vi == null) {
vi = inflater.inflate(R.layout.xmlfile, null);
holder = new ViewHolder();
holder.helloTxt= (TextView) vi.findViewById(R.id.hearTxt);
holder.parentLayout= (RelativeLayout) vi
.findViewById(R.id.parentLayout);
vi.setTag(holder);
}else
holder=(ViewHolder)vi.getTag();
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(activity.getApplicationContext(),
" " + position, Toast.LENGTH_SHORT).show();
holder.helloTxt.setText("Test");// not required
// just change the value of text in your list(which you are passing to the adapter) at corresponding position and then notify the list
notifyDataSetChanged();
Toast.makeText(activity.getApplicationContext(),
holder.helloTxt.getText().toString(),
Toast.LENGTH_LONG).show();
}
});
return vi;
It will display the text "test" but when you scroll, it will again changed to its original value so you have to change the value in the list also which you are sending to the adapter
Also in your case the problem is, when you update the text of your TextView, it gets updated for the time being that's why you are getting the TextView text in your Toast. But in order to show the updated text in ListView, you have to notify the List. But when you do so, your TextView resets to original value. So all you have to do is to take a global String variable and intialise that to your initial value whatever you want like this
private String yourText="initial text"
and in getView() set your TextView text to this variable like this
holder.helloTxt.setText(yourText);
and when you click your parentLayout,just assign, this string the value you want and notify the list
yourText="test";
notifyDataSetChanged();
and this will do the trick. But remember this works only when you have single row, if you have multiple rows you have to take a String array.

Do you perform a holder = vi.getTag(); in case the convertView not is null?
This is necessary when a view is already created to reinitialise it in the state it was.

Problem is, I am not able to change the text view text to "Test".
you are doing it wrong. Let's say your adapter is made of String. What I would have expected, is
if (convertView == null) {
// inflate stuff
// create older
// set the older in the converView's tag
} else {
// retriewholder
}
// here you set the String in the holder at position:
String tmpString = getItem(position);
holder.helloTxt.setText(tmpString);
holder.parentLayout.setTag(position);
Inside the onClick, you can retrieve the position trough the tag object, and update the String in the dataset and call notifyDataSetChanged

Your problem is you didnot touch the parent layout. Make sure that your finger can touch the parentLayout, you can add padding for it. Or you can try
holder.helloTxt.setOnClickListener(...)
instead of parentLayout.

I've seen a lot of ways but for me the simple way is pass component view to adapter. Then you can change you need. See an example below:
Link

Related

Radio Buttons Deselected on scrolling in custom listview

Radio Buttons Deselected on scrolling in custom listview
i have made custom listview that add
run time radiobutton added autimatically
but it deselected on scroll
my code given below of adapter and mainclass and activity files
Layout file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#drawable/gradient11"
android:layout_width="match_parent" android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioGroup
android:layout_width="match_parent"
android:layout_height="match_parent">
<RadioButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="option one is selected now so you can"
android:textColor="#00ff00"
android:id="#+id/op1"/>
<RadioButton
android:checked="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="op2"
android:textColor="#00ff00"
android:id="#+id/op2"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="op3"
android:textColor="#00ff00"
android:id="#+id/op3"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="op4"
android:textColor="#00ff00"
android:id="#+id/op4"/>
</RadioGroup>
</LinearLayout>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/quest"
android:textColor="#e2000000"/>
</LinearLayout>
The Adapter file
package com.patel.ravin.com.domparsing;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.RadioButton;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Created by lenovo on 08-08-2016.
*/
public class Adpt extends BaseAdapter
{
Context context;
ArrayList<MyBean> arrayList;
public Adpt(Context context,ArrayList<MyBean> arrayList)
{
this.context=context;
this.arrayList=arrayList;
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.listview, null);
TextView txtFName = (TextView) view.findViewById(R.id.qid);
TextView txtLName = (TextView) view.findViewById(R.id.quest);
RadioButton op1=(RadioButton)view.findViewById(R.id.op1);
RadioButton op2=(RadioButton)view.findViewById(R.id.op2);
RadioButton op3=(RadioButton)view.findViewById(R.id.op3);
RadioButton op4=(RadioButton)view.findViewById(R.id.op4);
MyBean myBean = arrayList.get(i);
txtFName.setText("" + myBean.getQid());
txtLName.setText(" Answer= " + myBean.getQname());
op1.setText(myBean.getOp1());
op2.setText(myBean.getOp2());
op3.setText(myBean.getOp3());
op4.setText(myBean.getOp4());
return view;
}
}
The Activity file
package com.patel.ravin.com.domparsing;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.patel.ravin.com.domparsing.AsyncTask.AsyncTaskLoader;
import com.patel.ravin.com.domparsing.AsyncTask.OnAsyncResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
public class MainActivity extends AppCompatActivity {
TextView textView;
ListView listView1;
Adpt adpt;
ArrayList<MyBean> arrayList=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// textView= (TextView) findViewById(R.id.tv1);
listView1=(ListView)findViewById(R.id.llv);
// Adpt adpt=new Adpt(getApplicationContext(),arrayList);
//listView.setAdapter(new ArrayAdapter<String>(getApplicationContext(),android.R.layout.simple_list_item_1,arrayList));
OnAsyncResult onAsyncResult=new OnAsyncResult() {
#Override
public void onAsyncResult(String result) {
Log.e("h", result.toString());
try {
// textView.setText(""+result.toString());
// String co=result.toString();
JSONArray jsonArray=new JSONArray(result);
MyBean myBean;
arrayList = new ArrayList<>();
for(int i=1;i<=jsonArray.length();i++)
{
JSONObject jsonObject=jsonArray.getJSONObject(i);
myBean = new MyBean();
myBean.setQid(jsonObject.getString("que"));
myBean.setQname(jsonObject.getString("ans"));
myBean.setOp1(jsonObject.getString("a"));
myBean.setOp2(jsonObject.getString("b"));
myBean.setOp3(jsonObject.getString("c"));
myBean.setOp4(jsonObject.getString("d"));
arrayList.add(myBean);
listView1.setAdapter(new Adpt(getApplicationContext(),arrayList));
}
//JSONObject object = new JSONObject(result);
//String contact = object.getString("que");
// textView.setText(co);
} catch (Exception e) {
e.printStackTrace();
}
}
};
AsyncTaskLoader asyncTaskLoader=new AsyncTaskLoader(MainActivity.this,onAsyncResult,null,"http://quiz/jsonapi.php");
asyncTaskLoader.execute();
}
}
Radio Buttons Deselected on scrolling in custom listview
i have made custom listview that add
run time radiobutton added autimatically
but it deselected on scroll
This is a very common problem in Android with Listviews and Radio buttons.
First, I would recommend you to check this post:
Using radio button in custom listview in Android
Now, I'm going to tell you which solution fits for me. In my case I use GridView, but it also works for ListView.
In your Adapter's class you have to have a variable for the selected item and his index, it could be something like:
private int mSelectedPosition = -1;
private RadioButton mSelectedRB;
Then, define a function to retrieve this information:
public int getItemSelected(){
return mSelectedPosition;
}
Now, In order to make it works properly, you have to user a ViewHolder (in my case every item in the GridView has a Image and a RadioButton), so you define your ViewHolder in the Adapter's class as well:
private class ViewHolder {
ImageView image;
RadioButton radio;
}
Then, in your getView function, you have to work with the ViewHolder. In the code I write comments to follow.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView; // assign the view
ViewHolder holder; // declare the ViewHolder
if(view == null){
// cutom layout for each row (item) of the ListView
view = mLayoutInflater.inflate(R.layout.item_list_company, parent, false);
holder = new ViewHolder();
// initialize the ViewHolder's field
holder.image = (ImageView) view.findViewById(R.id.c1);
holder.radio = (RadioButton)view.findViewById(R.id.cN1);
view.setTag(holder); // set the tag
}else{ // already initialized
holder = (ViewHolder)view.getTag(); // so we only set the tag
}
// on click triggered for each RadioButton in the ListView
holder.radio.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(position != mSelectedPosition && mSelectedRB != null){
mSelectedRB.setChecked(false); // uncheck the last one
}
mSelectedPosition = position; // change the item selected index
mSelectedRB = (RadioButton)v; // assign the new item selected
}
});
// just to control the right item checked
if(mSelectedPosition != position){
holder.radio.setChecked(false);
}else{
holder.radio.setChecked(true);
if(mSelectedRB != null && holder.radio != mSelectedRB){
mSelectedRB = holder.radio;
}
}
return view;
}
Finally, in the custom layout (item_list_company.xml in my case) for each item in the ListView, I have the following code:
<?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:layout_height="match_parent">
<ImageView android:id="#+id/c1"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_gravity="center"
android:scaleType="centerInside" />
<RadioButton
android:id="#+id/cN1"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:buttonTint="#color/colorPrimary"
android:textColor="#color/colorAccent"
android:focusable="false"
android:layout_gravity="left"
android:clickable="false"
android:focusableInTouchMode="false"
android:textSize="20dp"/>
</LinearLayout>
Special attention for this three attributes of the RadioButton:
android:focusable="false"
android:clickable="false"
android:focusableInTouchMode="false"
So, with all of this, you only have to set your adapter and ListView in your Activity and call to the right function to retrieve the selected item:
ArrayList<MyBean> arrayList = new ArrayList<>();
ListView listView1 = (ListView)findViewById(R.id.llv);
Adpt adpt = new Adpt(getApplicationContext(), arrayList);
// add data to the ArrayList
adpt.notifyDataSetChanged(); // notify for the new data in the ArrayList
// retrieve the item selected
int selected = adpt.getItemSelected();
Hope it helps!

Checking a few CheckBoxes in a ListView results in checking another CheckBox

I'm back with a question.
First, please take a look at this image here: Image 1: Click here
What I am trying to do here is make the CheckBox (cb_exercisedone) get checked automatically when the user checks all the ones in the sets (cb_setdone). A simple idea but maybe my list Adapter is what made it almost impossible for me, because I tried to make it work for hours and of course read a dozen similar questions here on SO.Lets cut to the chase, here is my code:
ExerciseAdapter.java
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
import com.example.workoutapp.R;
import com.rabiiapps.model.Exercise;
public class ExerciseAdapter extends ArrayAdapter<Exercise> {
private ArrayList<Exercise> exercises;
private LayoutInflater inflater;
// list with title positions in listview
public static List<Integer> HEADER_VIEW_LIST = new ArrayList<Integer>();
public ExerciseAdapter(Context context, int textViewResourceId, ArrayList<Exercise> objects) {
super(context, textViewResourceId, objects);
exercises = objects;
inflater = (LayoutInflater) getContext().
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getItemViewType(int position) {
for(int i=0; i<HEADER_VIEW_LIST.size(); i++) {
if (position == HEADER_VIEW_LIST.get(i)) return 0;
}
return 1;
}
#Override
public int getViewTypeCount() {
return 2; // two types of rows, exercise headers and bodies (sets)
}
public View getView(final int position, View convertView, ViewGroup parent){
View view = convertView;
Holder holder = null;
if (getItemViewType(position) == 0) {
if (view == null) {
view = inflater.inflate(R.layout.item_exercise_header, null);
holder = new Holder();
holder.exerciceTitleView = (TextView) view.findViewById(R.id.tv_exercice_title);
view.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
Exercise exercise = exercises.get(position);
if (exercise != null)
holder.exerciceTitleView.setText(exercise.getTitle());
holder.cbExercise = (CheckBox) view.findViewById(R.id.cb_exercisedone);
} else {
if (view == null) {
view = inflater.inflate(R.layout.item_set, null);
holder = new Holder();
holder.setCounterView = (TextView) view.findViewById(R.id.tv_set_counter);
view.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
Exercise exercice = exercises.get(position);
if (exercice != null)
holder.setCounterView.setText(String.valueOf(exercice.getSetCount()));
}
return view;
}
static class Holder {
// header row items
CheckBox cbExercise;
TextView exerciceTitleView;
// body row item
CheckBox cbSet;
TextView setCounterView;
}
}
MediumActivity.java same as ProfessionalActivity which is in the image 1.
import java.util.ArrayList;
import com.example.workoutapp.R;
import com.rabiiapps.helper.ExerciseAdapter;
import com.rabiiapps.model.Exercise;
import android.app.ListActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
public class MediumActivity extends ListActivity {
private ArrayList<Exercise> mExercise = new ArrayList<Exercise>();
private Runnable viewParts;
private ExerciseAdapter adapter;
private TextView infoTextView;
private TextView programNameView;
private int positionCounter = 0;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_program);
// header
infoTextView = (TextView) findViewById(R.id.tv_program_info);
programNameView = (TextView) findViewById(R.id.tv_program_name);
programNameView.setText("Medium Program");
infoTextView.setText("Medium info goes here...");
/*
* back to our list
*/
// adapter
adapter = new ExerciseAdapter(this, R.layout.item_set, mExercise);
setListAdapter(adapter);
// here we are defining our runnable thread.
viewParts = new Runnable(){
public void run(){
handler.sendEmptyMessage(0);
}
};
Thread thread = new Thread(null, viewParts, "WorkoutThread");
thread.start();
ExerciseAdapter.HEADER_VIEW_LIST.clear(); // lose title positions when done
}
private Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
// Sets + reps etc for medium
addExercice("Medium training 1", 2);
addExercice("Medium training 2", 4);
addExercice("Medium training 3", 3);
adapter = new ExerciseAdapter(MediumActivity.this, R.layout.item_set, mExercise);
setListAdapter(adapter);
}
};
public void addExercice(String title, int sets) {
mExercise.add(new Exercise(title));
ExerciseAdapter.HEADER_VIEW_LIST.add(positionCounter);
positionCounter++;
for(int i=1; i<sets+1; i++) {
mExercise.add(new Exercise(i));
positionCounter++;
}
}
}
I'm not sure if you will need this but here is the layouts aswell:
activity_program.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/tv_program_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Program name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/tv_program_info"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_weight="0.20"
android:text="program info, talk abt sets, reps, weight etc..." />
<ListView
android:id="#+id/android:list"
android:layout_width="match_parent"
android:layout_height="395dp" >
</ListView>
<Button
android:id="#+id/bt_savework"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.03"
android:text="Save Workout" />
</LinearLayout>
item_exercise_header.xml
<?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"
android:padding="5dp" >
<TextView
android:id="#+id/tv_exercice_title"
android:layout_width="270dp"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/cb_exercisedone"
android:layout_alignParentTop="true"
android:gravity="center_vertical"
android:text="Exercice title"
android:textAppearance="?android:attr/textAppearanceMedium" />
<CheckBox
android:id="#+id/cb_exercisedone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:enabled="false" />
</RelativeLayout>
item_set.xml
<?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"
android:padding="5dp" >
<LinearLayout
android:id="#+id/ll_set"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:orientation="horizontal" >
<CheckBox
android:id="#+id/cb_setdone"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tv_set"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="7dp"
android:text="Set" />
<TextView
android:id="#+id/tv_set_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="3dp"
android:text="1" />
<TextView
android:id="#+id/tv_reps"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:text="Reps x" />
<EditText
android:id="#+id/et_reps_number"
android:layout_width="47dp"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number" />
<TextView
android:id="#+id/tv_weight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:text="Weight" />
<EditText
android:id="#+id/et_weight_number"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number" />
<TextView
android:id="#+id/tv_weight_unit"
android:layout_width="59dp"
android:layout_height="wrap_content"
android:text="kg/lbs"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</RelativeLayout>
Please help me with your ideas, for the problem of the checkbox mainly but if you see there could be any enhancement in the way I handled the listView or anything else feel free to let me know in your answer. Thank you for reading.
Edit: I solved it, I used the positions in the listview and the number of sets.
first you need to get the count of all the item in the list view.
Listview.getCount(); where the listview is the array used to populate the Adapter.
Now let us say the number of item is 20.
each time you check a checkbox, decrement the count by one, once the count is 0, then you can set the final checkboxe checked.
random example
int count = list.getCount();
In the adapter
check_box.setOnclickListener(new OnClickListener(){
#Override
public void onClick(View v){
if(check_box.isChecked(){
count--;
}else{
//if you uncheck the box, then increment the count
count++;
}
//now check if all check_boxes are checked
if(count==0)
// code to check the last checkBox because all are checked
else
//code to uncheck the last checkbox if it was checked and you just unchecked a boxe
}
});
It should be something like this :
in your activity, create the variable count
int count = mExercise.size();//this will give you the amount of checkboxes
then in your adapter :
public View getView(final int position, View convertView, ViewGroup parent){
View view = convertView;
Holder holder = null;
if (getItemViewType(position) == 0) {
if (view == null) {
view = inflater.inflate(R.layout.item_exercise_header, null);
holder = new Holder();
holder.exerciceTitleView = (TextView) view.findViewById(R.id.tv_exercice_title);
view.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
Exercise exercise = exercises.get(position);
if (exercise != null)
holder.exerciceTitleView.setText(exercise.getTitle());
holder.cbExercise = (CheckBox) view.findViewById(R.id.cb_exercisedone);
} else {
if (view == null) {
view = inflater.inflate(R.layout.item_set, null);
holder = new Holder();
holder.setCounterView = (TextView) view.findViewById(R.id.tv_set_counter);
view.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.cbExercise.setOnClickListener(new OnClickListener()){
#Override
public void onClick(View v){
if(holder.cbExercise.isChecked())
count--;
else
count++;
//now the final checkbox
if(count==0)
final_check_boxe.setChecked(true);
else
final_check_boxe.setChecked(false);
}
}
Exercise exercice = exercises.get(position);
if (exercice != null)
holder.setCounterView.setText(String.valueOf(exercice.getSetCount()));
}
return view;
}
I haven't try it but it should definitelly work
I fixed this after days of research and trying and this is the fix for everyone who stumbled upon the same problem:
holder.cbSet.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton button, boolean isChecked) {
if(isChecked)
mExercise.get(position).setCbChecked(true);
else
mExercise.get(position).setCbChecked(false);
}
});
holder.cbSet.setChecked(exercise.isCbChecked());

Android: can't apply onclick listener to button inside custom arrayadapter<String>

I'm trying to dynamically add click listeners to a custom array adapter for a list view. The idea is that I have list objects with text on them (eg "Group 1", "Group 2" etc.), and then when I click on the object a drop down appears ("expandable_section") with two buttons on it ("Members" and "Settings"). When I click on the members button I want to be able to access the specific text on the original group object. For example, clicking "Members" under the "Group 1" tab would give me access to the text "Group 1."
Here is my XML layout for the custom adapter object:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<!-- The list element for GROUP SETTINGS tab sub-section -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:paddingBottom="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp" >
<ImageView
android:id="#+id/activeIcon"
android:layout_width="34dp"
android:layout_height="34dp"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="5dp"
android:layout_marginLeft="-7dp"
android:layout_marginTop="5dp"
android:gravity="center_vertical" />
<ImageView
android:id="#+id/modeIcon"
android:layout_width="34dp"
android:layout_height="34dp"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="5dp"
android:layout_marginRight="15dp"
android:layout_marginTop="5dp"
android:gravity="center_vertical" />
<TextView
android:id="#+id/groupName"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:gravity="center_vertical"
android:textColor="#000000"
android:textSize="22dp" />
</LinearLayout>
<!-- SPECIAL HIDDEN TOOLBAR FOR DEMO LIBRARY LIST MODES TODO: Change to whitelist/blacklist GROUP TAB! -->
<!-- EXPANDABLEFOR GROUP-SETTINGS FRAGMENT -->
<LinearLayout
android:id="#+id/expandableSubsection"
android:layout_width="fill_parent"
android:layout_height="90dp"
android:layout_marginBottom="-100dp"
android:background="#dddddd"
android:gravity="center"
android:visibility="gone" >
<Button
android:id="#+id/groupMembersButton"
android:layout_width="150dp"
android:layout_height="40dp"
android:layout_marginRight="20dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Members" />
<Button
android:id="#+id/groupSettingsButton"
android:layout_width="150dp"
android:layout_height="40dp"
android:layout_marginRight="20dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Settings" />
</LinearLayout>
</LinearLayout>
Here is the custom adapter code:
package com.sapphire.view;
import java.util.List;
import com.sapphire.model.Mode;
import com.sapphire.view.ModeAdapter.ModeHolder;
import android.R;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class GroupAdapter extends ArrayAdapter<String>{
private Context context;
private int resource;
public GroupAdapter(Context context, int resource, int textViewResourceId,
List<String> objects) {
super(context, resource, textViewResourceId, objects);
this.context = context;
this.resource = resource;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi =(LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(this.resource, null);
}
Button but= (Button) v.findViewById(R.id.button1);
if( but!=null){
but.setId(position);
but.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("customgroup clicked !");
}
});
}
return v;
}
}
and here is where the custom adapter is actually used to display the list of groups:
public void displayGroupsOptions(){
final ListView lView = (ListView) thisView.findViewById(R.id.GroupsView);
final ArrayList<String> groupNameList = new ArrayList<String>();
lView.setAdapter(null); //empty the list view
//Get all groups from database table
System.out.println("customgroup about to get all groups from database");
List<Group> allGroups = db.getAllGroups();
if(!allGroups.isEmpty()){
for (Group g: allGroups){
groupNameList.add(g.getName());
}
//Convert group arraylist to group array for use in adapter for list view
String[] groupNameArray = (String[]) groupNameList.toArray(new String[0]);
GroupAdapter adapter = new GroupAdapter(getActivity().getApplicationContext(), R.layout.group_list_row, R.id.groupName, groupNameList);
lView.setAdapter(adapter);
// Creating an item click listener, to open/close the mode options toolbar for each item
lView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
View groupOptions = view.findViewById(R.id.expandableSubsection);
// Creating the expand animation for the item
ExpandAnimation ea = new ExpandAnimation(groupOptions, ANIMATION_DELAY);
// Start the animation on the toolbar
groupOptions.startAnimation(ea);
}
});
}
}
Any help would be appreciated! I just can't figure out for the life of me how to get the proper text to show up on the tab (right now it's blank) and how to make the onclick listener actually attach and work. Thanks!
You can set tag for your Button in getView method to pass the position argument, and get the tag in th ClickListener.
btn.setTag(position);
#Override
public void onClick(View v) {
int position = (Integer)v.getTag();
}
Even you can set other view in the same adapter item as a tag and pass it to the listener.
use this piece of code where you used getView in adapter class
public class ViewHolder {
Button b;
}
and also this
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.xyz,
parent, false);
holder.b = (Button) convertView.findViewById(R.id.button1);
convertView.setTag(holder);
}
else{
holder = (ViewHolder) convertView.getTag();
}
Item it = item.get(position);
holder.b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("customgroup clicked !");
}
});
return convertView;
}

cant get sections to work in contact app/listview

I've been through every stack discussion on this I could find, along with about a dozen tutorials. I'm just not getting it. I'm using 'getItemViewType' to determine which layout I should use. Here's where I run into a problem (and maybe the way I'm getting the position is the root issue, not sure):
What I'm doing is getting the first character of the contact's name at position x. If it's different than the first character in position x-1, I know that it's the next letter in the list and it needs a section header, which would be inserted ABOVE the current list item. How do I get my adapter to add a new layout in position x-1?
This is my adapter code. I've stripped the code which was causing the app to force close, which leaves me with just the 1 layout. I can't figure out how to insert the 'section' layout at position x-1. Below the adapter code I threw in the xml for my 2 layouts. Let me know if you need anything else. Thanks in advance.
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class ContactNameAdapter extends BaseAdapter {
public static final int CONTACT_NAME = 0;
public static final int ALPHA_HEADER = 1;
private static final int NUMBER_OF_LAYOUTS = 2;
Context context;
private ArrayList<ListItemDetails> sItemDetailsArrayList;
public ContactNameAdapter(ArrayList<ListItemDetails> data, Context context) {
sItemDetailsArrayList = data;
this.context = context;
}
#Override
public int getCount() {
return sItemDetailsArrayList.size();
}
#Override
public ListItemDetails getItem(int position) {
return sItemDetailsArrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getViewTypeCount() {
return NUMBER_OF_LAYOUTS;
}
#Override
public int getItemViewType(int position) {
if (position != 0) {
if (getItem(position).getName().toUpperCase().charAt(0) == getItem(
position - 1).getName().toUpperCase().charAt(0)) {
return CONTACT_NAME;
} else {
return ALPHA_HEADER;
}
} else {
return ALPHA_HEADER;
}
}
#Override
public View getView(int position, View view, ViewGroup parent) {
ImageView mImageView;
TextView mTextView;
if (view == null) {
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.contactlistlayout, null);
mImageView = (ImageView) view.findViewById(R.id.ivContactPhoto);
mTextView = (TextView) view.findViewById(R.id.textView1);
view.setTag(new ViewHolder(mImageView, mTextView));
} else {
ViewHolder viewHolder = (ViewHolder) view.getTag();
mImageView = viewHolder.mImageView;
mTextView = viewHolder.mTextView;
}
ListItemDetails listItemDetails = getItem(position);
mTextView.setText(listItemDetails.getName());
mImageView.setImageBitmap(listItemDetails.getImage());
if (listItemDetails.getImage() == null) {
mImageView.setImageResource(R.raw.default_contact);
}
return view;
}
private static class ViewHolder {
public final TextView mTextView;
public final ImageView mImageView;
public ViewHolder(ImageView mImageView, TextView mTextView) {
this.mImageView = mImageView;
this.mTextView = mTextView;
}
}
}
list layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/contactView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:paddingLeft="2dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/ivContactPhoto"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false" />
</RelativeLayout>
section layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layoutView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical" >
<TextView
android:id="#+id/tvAlphaHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true"
android:paddingBottom="10dp"
android:paddingLeft="2dp"
android:paddingTop="10dp"
android:textAppearance="?android:attr/textAppearanceSmall" />
<ImageView
android:id="#+id/ivSectionLine"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#android:color/holo_blue_light"
android:focusable="true" />
</LinearLayout>
I've looked at a bunch of tutorials that ended up confusing me more than helping me, but I found this one to be great. If you've been around the world on this like I have, take a look at this tutorial :)
http://codelikes.blogspot.com/2012/04/android-alphabet-listview-like-contacts.html?zx=d40863f078ab91b4

Page curl animation to flip between views of a viewflipper

I've come across several examples of the page curl animation as well as viewflippers . Is it possible to navigate between children of a viewflipper via a page curl animation . The animations i have applied to viewflippers till now were very basic such as a slide-in/slide-out and I was wondering if the same could be done/has already be implemented using a page-curl animation.
There is an open source android project here: http://code.google.com/p/android-page-curl/.
I found another one here: https://github.com/harism/android_page_curl/.
But there is no native implementation if that is what you are asking.
You need to import one module library for this, from HERE
After that use following code:-
item_page.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/image"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:contentDescription="#string/app_name"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/text"
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMediumInverse"
android:textColor="#android:color/black" />
</LinearLayout>
</ScrollView>
activity_flipper_view_controller.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:flip="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/darker_gray"
android:paddingLeft="10dp"
android:text="#string/header"
android:textAppearance="#android:style/TextAppearance.Large" />
<com.aphidmobile.flip.FlipViewController
android:id="#+id/flip_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
flip:orientation="horizontal" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/darker_gray"
android:paddingLeft="10dp"
android:text="#string/footer"
android:textAppearance="#android:style/TextAppearance.Large" />
</LinearLayout>
FlipperAdapter.java
package pratiksha.com.pagecurlviewdemo;
import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
import pratiksha.com.pagecurlviewdemo.R;
/**
* Created by User(LPT-APR2015-02) on 11/7/2016.
*/
public class FlipperAdapter extends BaseAdapter {
private AppCompatActivity appCompatActivity;
private List<String> strings;
private int[] drawableIds = {R.mipmap.ic_launcher, R.mipmap.page1, R.mipmap.page2, R.mipmap.ic_launcher,
R.mipmap.page2, R.mipmap.page1, R.mipmap.page2, R.mipmap.ic_launcher,
R.mipmap.page1};
public FlipperAdapter(AppCompatActivity appCompatActivity, List<String> strings) {
super();
this.strings = strings;
this.appCompatActivity = appCompatActivity;
}
#Override
public int getCount() {
return strings.size();
}
#Override
public String getItem(int position) {
return strings.get(position);
}
#Override
public long getItemId(int position) {
return strings.indexOf(getItem(position));
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
LayoutInflater inflater = (LayoutInflater) appCompatActivity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
// If holder not exist then locate all view from UI file.
if (convertView == null) {
// inflate UI from XML file
convertView = inflater.inflate(R.layout.item_page, parent, false);
// get all UI view
holder = new ViewHolder(convertView);
// set tag for holder
convertView.setTag(holder);
} else {
// if holder created, get tag from view
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(getItem(position));
holder.imageView.setImageResource(drawableIds[position]);
return convertView;
}
private static class ViewHolder {
private TextView textView;
private ImageView imageView;
public ViewHolder(View v) {
imageView = (ImageView)v.findViewById(R.id.image);
textView = (TextView) v.findViewById(R.id.text);
}
}
}
Main Activity.java
package pratiksha.com.pagecurlviewdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.aphidmobile.flip.FlipViewController;
import java.util.ArrayList;
public class FlipperViewController extends AppCompatActivity {
private FlipViewController flipViewController;
private FlipperAdapter adapter;
private ArrayList<String> stringArrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flipper_view_controller);
flipViewController = (FlipViewController)findViewById(R.id.flip_view);
stringArrayList = new ArrayList<>();
readDataFromAssets();
//create and attach adapter to flipper view
adapter = new FlipperAdapter(this, stringArrayList);
flipViewController.setAdapter(adapter);
}
private void readDataFromAssets() {
for(int i=1;i<10;i++)
stringArrayList.add("Page Number "+i);
}
}

Categories

Resources