Thijs V Thijs V - 3 years ago 35
Android Question

Passing selected value to another activity (using recycleview/textView)

i'm making a pokedex app and i'm stuck at passing the data of the selected pokemon to another activity(to show more details). The problem is that it keeps sending the same value to the other activity(the first value in the list, in this case bulbasaur) even if i select a different pokemon.

The list consists of a recycleview, textView and a imageView.And i use the value of the textView as data to send to the other activity.

So i want to pass the correct name(textView) from the selected pokemon to the other activity as i click the image. And im not sure what i'm missing.

Thanks in advance!




Adapter code

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

private ArrayList<Pokemon> dataset;
private Context context;

public PokemonListAdapter(Context context){
this.context = context;
dataset = new ArrayList<>();
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_pokemon, parent,false);
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position){
Pokemon p = dataset.get(position);
holder.pokemonTextView.setText(p.getName());

Glide.with(context).load("http://pokeapi.co/media/sprites/pokemon/" + p.getNumber() + ".png")
.centerCrop()
.crossFade()
.into(holder.pictureImageView);

}

@Override
public int getItemCount(){
return dataset.size();
}

public void toegevoegdePokemonList(ArrayList<Pokemon> pokemonList) {
dataset.addAll(pokemonList);
notifyDataSetChanged();
}

public class ViewHolder extends RecyclerView.ViewHolder{
private ImageView pictureImageView;
private TextView pokemonTextView;


public ViewHolder(View itemView) {
super(itemView);
pictureImageView = (ImageView) itemView.findViewById(R.id.pictureImageView);
pokemonTextView = (TextView) itemView.findViewById(R.id.pokemonTextView);
}
}





First activity (List)

public class Pokedex extends AppCompatActivity {

private Retrofit retrofit;
private static final String TAG = "POKEDEX";
private RecyclerView recyclerView;
private PokemonListAdapter pokemonListAdapter;
private int offset;
private boolean loaded;

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

//recycleViewer
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
pokemonListAdapter = new PokemonListAdapter(this);
recyclerView.setAdapter(pokemonListAdapter);
recyclerView.setHasFixedSize(true);

//grid
final GridLayoutManager layoutManager = new GridLayoutManager(this, 3);
recyclerView.setLayoutManager(layoutManager);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);

if(dy > 0){
int visibleItemCount = layoutManager.getChildCount();
int totalItemCount = layoutManager.getItemCount();
int partVisible = layoutManager.findFirstVisibleItemPosition();

if(loaded){
if((visibleItemCount + partVisible) >= totalItemCount){
Log.i(TAG, "Final");
loaded = false;
offset += 20;
getDataPokemon(offset);
}
}
}
}
});

//retrofit
retrofit = new Retrofit.Builder()
.baseUrl("http://pokeapi.co/api/v2/")
.addConverterFactory(GsonConverterFactory.create())
.build();

loaded = true;
offset = 0;

getDataPokemon(offset);
}


//method
private void getDataPokemon(int offset) {
apiService service = retrofit.create(apiService.class);
Call<PokemonRequest> pokemonRequestCall = service.getPokemonList(20, offset);

pokemonRequestCall.enqueue(new Callback<PokemonRequest>() {
@Override
public void onResponse(Call<PokemonRequest> call, Response<PokemonRequest> response) {
loaded = true;
if (response.isSuccessful()) {

PokemonRequest pokemonRequest = response.body();
ArrayList<Pokemon> pokemonList = pokemonRequest.getResults();

pokemonListAdapter.toegevoegdePokemonList(pokemonList);

} else {
Log.e(TAG, "onResponse: " + response.errorBody());
}
}

@Override
public void onFailure(Call<PokemonRequest> call, Throwable t) {
loaded = true;
Log.e(TAG, "onFailure: " + t.getMessage());
}

});
}


public void pokemon_onClick(View v)
{
TextView textView = (TextView)findViewById(R.id.pokemonTextView);
Intent intent = new Intent();
intent.putExtra("pokemonName", textView.getText().toString());
intent.setClass(this, PokemonDetail.class);
startActivity(intent);
}





Xml layout file (first activity)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="be.thomasmore.project_idexv2.Pokedex">

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







xml layout file(which shows the image and text)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">

<ImageView
android:id="@+id/pictureImageView"
android:layout_width="96dp"
android:layout_height="96dp"
android:layout_gravity="center_horizontal"
android:onClick="pokemon_onClick"/>

<TextView
android:id="@+id/pokemonTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:gravity="center_horizontal"/>
<!--android:textAllCaps="true"-->







2nd activity

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

String pokemon = getIntent().getExtras().getString("pokemonName");
TextView textView = (TextView)findViewById(R.id.pokemonName);
textView.setText(pokemon);
}

Answer Source

It won't work this way. When pokemon_onClick() is called, the findViewById will return the first occurance of view with id pokemonTextView. That's why you are recieving the same value in your second Activity.

The simplest solution is to implement onClickListener in your ViewHolder and start the 2nd Activity directly from there.

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        private ImageView pictureImageView;
        private TextView pokemonTextView;

    public ViewHolder(View itemView) {
        super(itemView);

        itemView.setClickable(true);
        itemView.setOnClickListener(this);

        pictureImageView = (ImageView) itemView.findViewById(R.id.pictureImageView);
        pokemonTextView = (TextView) itemView.findViewById(R.id.pokemonTextView);
    }

    @Override
    public void onClick(View v) {
        Intent intent = new Intent(context, PokemonDetail.class);
        intent.putExtra("pokemonName", dataset.get(getAdapterPosition()).getName());
        context.startActivity(intent);
    }
}

Little bit more complex but better solution would be to create an interface and handle click callbacks inside your Activity:

Create interface inside your adapter and provide setter:

private PokemonClickListener listener;

public void setListener(PokemonClickListener listener) {
    this.listener = listener;
}

public interface PokemonClickListener{
    void onPokemonClicked(Pokemon pokemon);
}

Implement OnClickListener in ViewHolder as above, but call listener method instead of starting the 2nd Activity:

@Override
public void onClick(View v) {
    if(listener != null){
        listener.onPokemonClicked(dataset.get(getAdapterPosition()));
    }
}

In your acitivty, implement PokemonClickListener and set the listener to the adapter.

adapter.setListener(new PokemonClickListener() {
    @Override
    public void onPokemonClicked(Pokemon pokemon) {
        Intent intent = new Intent(this, PokemonDetail.class);
        intent.putExtra("pokemonName", pokemon.getName());
        startActivity(intent);
    }
});
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download