#StackBounty: #android #android-recyclerview #recycler-adapter #android-viewholder How to detect each RecyclerView item after it is dis…

Bounty: 150

I want to detect each item in my RecylerView after it is displayed to the user.

Basically, I am trying to play a sound on each item after it is loaded on the screen.
But I am not able to detect whenever each item is loaded on the screen! Is there any method I have to call to detect each item rendered

E.g 1st RecyclerView item displayed -> play sound
    2st RecyclerView item displayed -> play sound...

My Adapter class looks like this –

public class AdapterListAnimation extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<Multiples> items = new ArrayList<>();

    private Context ctx;
    private OnItemClickListener mOnItemClickListener;
    private int animation_type = 0;
    .........
    .........

EDIT:
I am calling this init component() method from onCreated() method, can you able to give advice on what should i do to achieve my goal as described above

 private void initComponent() {
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setHasFixedSize(true);
        items = DataGenerator.getPeopleData(this,of,value);
        setAdapter();
       /* MediaPlayer mp=MediaPlayer.create(this, R.raw.sword);
        if (mp.isPlaying()) {
            mp.stop();
            mp.release();
            mp = MediaPlayer.create(this, R.raw.sword);
        } mp.start();*/

    }

    private void setAdapter() {
        //set data and list adapter
        mAdapter = new AdapterListAnimation(this, items, animation_type);
        recyclerView.setAdapter(mAdapter);

        // on item list clicked
        mAdapter.setOnItemClickListener(new AdapterListAnimation.OnItemClickListener() {
            @Override
            public void onItemClick(View view, com.math.multiplication.model.Multiples obj, int position) {
                Snackbar.make(parent_view, "Item " + obj.first + " clicked", Snackbar.LENGTH_SHORT).show();
            }
        });
    }


Get this bounty!!!

#StackBounty: #java #android #android-recyclerview Unable to Show imageView in recyclerVIew

Bounty: 200

How can i show/Hide imageView in recyclerView as TTS(text to speech) plays for all the available list items, one by one!

Activity method
-This method is called r with Loop(not working, no bugs but simply do not give my expected output

int position=0;
    public void convertTextToSpeech() {
        Multiples multiples1=items.get(position);
        for (Multiples item : items) {

            text = item.first + "  " + item.getSecond() + " Za " + item.getResult() + ".";
            tts.speak(text, TextToSpeech.QUEUE_ADD, null);
            boolean speakingEnd = tts.isSpeaking();


            if(speakingEnd){
                Toast.makeText(getApplicationContext(), "Speaking...."+position, Toast.LENGTH_SHORT).show();
                multiples1.setImage_show(true);
                mAdapter.notifyItemChanged(position);

            } else {
                Toast.makeText(getApplicationContext(), "Done...."+position, Toast.LENGTH_SHORT).show();
            }
            position++;
        }
    }

The complete code is below for more understanding,

https://i.stack.imgur.com/ddfNz.jpg

https://i.stack.imgur.com/OZvG2.png

Adapter:
enter image description here

First, i displayed all items in recyclerView. Afterward, I am calling the displayed item in a method having for loop to TTS play each rows(list item). The problem i am facing now is the imageView is not displaying as each recyclerView item are being read by TTS.

Expected output is whenever TTS plays for each row item textView, An imageView(#image1) should show simultaneously




UPDATED TRIED CODE

DisplayActivityResultAdapter.java

 package com.math.multiplication.activity;

import android.content.Intent;
import android.os.Handler;
import android.speech.tts.TextToSpeech;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import com.math.multiplication.R;
import com.math.multiplication.adapter.MyAdapter;
import com.math.multiplication.data.DataGenerator;
import com.math.multiplication.model.Multiples;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class DisplayResultActivity extends AppCompatActivity {

    String of = "";
    String text;
    String value = "";
    private RecyclerView recyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager layoutManager;
    TextToSpeech tts;



    private List<Multiples> items = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_display_result);
        initToolbar();

        recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
      //  recyclerView.setHasFixedSize(true);

        // use a linear layout manager
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        // specify an adapter (see also next example)
        items.addAll(DataGenerator.getPeopleData(this, of, value));
        mAdapter = new MyAdapter(items);
        recyclerView.setAdapter(mAdapter);

        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                //Do something after 100ms
                //   Toast.makeText(getApplicationContext(), "-----------done--------", Toast.LENGTH_SHORT).show();
                tts = new TextToSpeech(DisplayResultActivity.this, new TextToSpeech.OnInitListener() {
                    @Override
                    public void onInit(int status) {
                        // TODO Auto-generated method stub
                        if (status == TextToSpeech.SUCCESS) {
                            int result = tts.setLanguage(Locale.US);
                            if (result == TextToSpeech.LANG_MISSING_DATA ||
                                    result == TextToSpeech.LANG_NOT_SUPPORTED) {
                                Log.e("error", "This Language is not supported");
                            } else {
                                convertTextToSpeech();
                            }
                        }
                    }
                });
            }
        }, 2500);


    }

    int position = 0;
    public void convertTextToSpeech() {
        Multiples multiples1=items.get(position);
        for (Multiples item : items) {
            text = item.first + "  " + item.getSecond() + " Za " + item.getResult() + ".";
            tts.speak(text, TextToSpeech.QUEUE_ADD, null);
            boolean speakingEnd = tts.isSpeaking();

            // Toast.makeText(getApplicationContext(), "Speaking...."+position, Toast.LENGTH_SHORT).show();
           // multiples1.setImage_show(true);
            //  mAdapter.notifyItemChanged(position);
           // Log.i("values","------------------------------------------Row value-"+item.getFirst()+" X "+item.getSecond()+", Position="+position);
             //------------------------
            MyAdapter m= (MyAdapter)  mAdapter;
            m.updateItem(item,position);
            position++;
        }
    }



    private void initToolbar() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setNavigationIcon(R.drawable.ic_arrow_back);

        setSupportActionBar(toolbar);
        Intent intent = getIntent();
        of = intent.getStringExtra(DisplayMultipleList.MULTIPLE_OF);
        value = intent.getStringExtra(DisplayMultipleList.MULTIPLE_VALUE);
        getSupportActionBar().setTitle(value + " times table");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        // getSupportActionBar().setDisplayShow
        //  Tools.setSystemBarColor(this);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_setting, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
        } else {
            //Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(this, SettingFlat.class);
            startActivity(intent);
        }
        return super.onOptionsItemSelected(item);
    }
}

MyAdapter.java

    package com.math.multiplication.adapter;

import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.math.multiplication.R;
import com.math.multiplication.model.Multiples;

import java.util.ArrayList;
import java.util.List;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private String[] mDataset;
    private List<Multiples> items = new ArrayList<>();


    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public ImageView image;
        public ImageView image1;
        public TextView name;
        public View lyt_parent;

        public MyViewHolder(View v) {
            super(v);
            image = (ImageView) v.findViewById(R.id.image);
            image1 = (ImageView) v.findViewById(R.id.image1);
            name = (TextView) v.findViewById(R.id.name);
            lyt_parent = (View) v.findViewById(R.id.lyt_parent);
        }
    }
    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(List<Multiples> myDataset) {
        items = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_people_chat, parent, false);
        MyViewHolder vh = new MyViewHolder(v);
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element

        if (holder instanceof MyAdapter.MyViewHolder) {
            final MyAdapter.MyViewHolder view = (MyAdapter.MyViewHolder) holder;
            Multiples p = items.get(position);
            view.name.setText(p.first + " X " + p.getSecond() + "= "+p.getResult());


            if(position>0) {
                if (p.image_show) {
                    view.image1.setVisibility(View.VISIBLE);
                    view.image.setVisibility(View.INVISIBLE);
                } else {
                    view.image1.setVisibility(View.INVISIBLE);
                    view.image.setVisibility(View.VISIBLE);
                }
            }
        }

    }


    public void updateItem(Multiples newItem, int pos) {
        Log.i("values","-----In updateItem Log----Row value-"+newItem.getFirst()+" X "+newItem.getSecond()+", Position="+pos);
        items.set(pos, newItem); //update passed value in your adapter's data structure
        Log.e("msg","-----items.get(pos)------------->"+items.get(pos).getFirst()+" X " +items.get(pos).getSecond());

        notifyItemChanged(pos,newItem);
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return items.size();
    }
}

Multiples.java(model class)

package com.math.multiplication.model;

import android.graphics.drawable.Drawable;

public class Multiples {
    public int image;
    public Drawable imageDrw;

    public String first;
    public String second;
    public  String result;
    public boolean image_show=false;  // i have added this new variable , having getter & setters, & in construction
    public  Multiples(){

    }
    public Multiples(int image, Drawable imageDrw, String first, String second, String result, String readType,boolean image_show) {
        this.image = image;
        this.imageDrw = imageDrw;
        this.first = first;
        this.second = second;
        this.result = result;
        this.readType = readType;
        this.image_show = image_show;
    }

    public String readType;

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }

    public Drawable getImageDrw() {
        return imageDrw;
    }

    public void setImageDrw(Drawable imageDrw) {
        this.imageDrw = imageDrw;
    }

    public String getFirst() {
        return first;
    }

    public void setFirst(String first) {
        this.first = first;
    }

    public String getSecond() {
        return second;
    }

    public void setSecond(String second) {
        this.second = second;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public String getReadType() {
        return readType;
    }

    public void setReadType(String readType) {
        this.readType = readType;
    }

    public boolean isImage_show() {
        return image_show;
    }

    public void setImage_show(boolean image_show) {
        this.image_show = image_show;
    }
}

xml recyclerView item

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <com.balysv.materialripple.MaterialRippleLayout
        android:id="@+id/lyt_parent"
        style="@style/RippleStyleBlack"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:focusable="true">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="@color/grey_10" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center_vertical"
                android:orientation="horizontal"
                android:textAlignment="gravity" >

                <View
                    android:layout_width="@dimen/spacing_large"
                    android:layout_height="wrap_content" />

                <ImageView
                    android:id="@+id/image"
                    android:layout_width="35dp"
                    android:layout_height="35dp"
                    android:background="@android:color/transparent"
                    android:src="@drawable/ic_arrow_right" />

                <ImageView
                    android:id="@+id/image1"
                    android:layout_width="51dp"
                    android:layout_height="35dp"
                    android:background="@android:color/transparent"
                    android:src="@drawable/ic_arrow_right"
                    android:visibility="invisible" />

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:paddingBottom="@dimen/spacing_middle"
                    android:paddingTop="@dimen/spacing_middle">

                    <TextView
                        android:id="@+id/name"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginEnd="@dimen/spacing_middle"
                        android:layout_marginRight="@dimen/spacing_middle"
                        android:fontFamily="sans-serif-condensed"
                        android:gravity="center|left"
                        android:text="36"
                        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
                        android:textColor="@color/grey_80"
                        android:textSize="30sp"

                        />
                </LinearLayout>
                <View
                    android:layout_width="@dimen/spacing_large"
                    android:layout_height="match_parent" />
            </LinearLayout>
            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="@color/grey_10" />
        </LinearLayout>
    </com.balysv.materialripple.MaterialRippleLayout>
</RelativeLayout>

RecyclerView xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <include layout="@layout/toolbar" />
    </android.support.design.widget.AppBarLayout>

    <RelativeLayout
        android:id="@+id/root_display_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/gradient_animation"><![CDATA[
        android:scrollingCache="true" />
        ]]>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="vertical"
            android:scrollingCache="true" />

    </RelativeLayout>

</LinearLayout>


Get this bounty!!!

#StackBounty: #android #android-recyclerview #android-radiogroup Checked RadioButton Recycling

Bounty: 100

I’m adding radiogroups programatically to my recyclerview and it’s working fine.
But when I check it and scroll the recyclerview it loses checked radios.

I’ve seen many ways and examples of solutions, but I cannot achieve it. It’s been some days in a row.

I’m saving the checked radio in model as you can see in code below.

Adapter:

@Override
public void onBindViewHolder(final NROptionLineHolder holder, int position) {

    holder.priceGroup.removeAllViews();
    holder.priceGroup.setOnCheckedChangeListener(null);

    int id = (position+1)*100;
    checklistModel = mChecklists.get(position);
    holder.packageName.setText(checklistModel.getTitle());

    for(String price : checklistModel.getQuestions()){
        RadioButton rb = new RadioButton(NROptionLineAdapter.this.context);
        rb.setId(id++);
        rb.setText(price);
        holder.priceGroup.addView(rb);
    }
    holder.priceGroup.check(checklistModel.getSelectedId());

    holder.priceGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            checklistModel.setSelectedId(checkedId);
            Log.d(TAG, "onCheckedChanged: " + checkedId);
        }
    });

}

Holder

    OnNROptionListener onNROptionListener;

    public NROptionLineHolder(View itemView, OnNROptionListener onNROptionListener) {
        super(itemView);

        packageName = itemView.findViewById(R.id.package_name);
        priceGroup = itemView.findViewById(R.id.price_grp);

//        priceGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
//            @Override
//            public void onCheckedChanged(RadioGroup radioGroup, int i) {
//
//                Log.d(TAG, "onCheckedChanged: " + radioGroup.getCheckedRadioButtonId() + " " + i);
//            }
//        });

        this.onNROptionListener = onNROptionListener;
        itemView.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        onNROptionListener.onNROptionClick(getAdapterPosition());
    }

    public interface OnNROptionListener {
        void onNROptionClick(int position);
    }
}

EDIT 1 – Radio Group

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/package_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <RadioGroup
        android:id="@+id/price_grp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/package_name"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:orientation="horizontal"/>
</android.support.constraint.ConstraintLayout>

EDIT 2

As requested, here is the important code from my ChecklistActivity

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_checklist);

    intent = getIntent();
    size = intent.getIntExtra("size", 0);
    nr = intent.getIntExtra("nr", 0);

    Log.d(TAG, "Checklist Activity - Qtd Questões: " + size);
    Log.d(TAG, "Checklist Activity - NR: " + nr);

    btnSaveCheck = findViewById(R.id.btnSaveChecklist);

    mRecyclerView = findViewById(R.id.package_lst);
    setupRecycler();

    btnSaveCheck.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(getApplicationContext(), "Sucesso", Toast.LENGTH_SHORT).show();
        }
    });
}

private void setupRecycler() {

    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    mRecyclerView.setLayoutManager(layoutManager);

    setupList();

    mAdapter = new NROptionLineAdapter(data, this, getApplication());
    mRecyclerView.setAdapter(mAdapter);

}

private void setupList(){
    data = new ArrayList<>();

    class setupList extends AsyncTask<Void, Void, List<MRNrOption>> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected List<MRNrOption> doInBackground(Void... voids) {

            list = DatabaseClient
                    .getInstance(getApplicationContext())
                    .getAppDatabase()
                    .mrNrOptionDAO()
                    .loadAllByNRId(nr);
            return list;

        }

        @Override
        protected void onPostExecute(List<MRNrOption> list) {
            super.onPostExecute(list);

            List<String> priceList = new ArrayList<>();
            priceList.add("Sim");
            priceList.add("Não");
            priceList.add("Não se Aplica");

            for (int i=0; i<list.size(); i++) {
                Log.d(TAG, "NRs Activity - Adding To List: " + list.get(i).getTitle());
                data.add(new Checklist(
                        list.get(i).getTitle(),
                        priceList)
                );

                mAdapter.notifyDataSetChanged();
            }

        }
    }

    setupList lm = new setupList();
    lm.execute();
}

RecyclerView with RadioButtons

EDIT 3 – Important

The RadioGroups and RadioButtons are programatically generated because I’m getting all questions from server, the number of questions are different depending on previous selections made by user, that’s why I need it this way.


Get this bounty!!!