Thijs V
Thijs V

Reputation: 13

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);
}

Upvotes: 1

Views: 2100

Answers (3)

Lenochod
Lenochod

Reputation: 61

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);
    }
});

Upvotes: 1

Mahesh Gawhane
Mahesh Gawhane

Reputation: 338

in your adapter ViewHolder class set itemView.OnClickListner() like

itemView.SetOnClickListner(new OnClickListner)
{
  @override
  OnClick()
  {
     String txt_value = yourText.getText().toString();
     Intent i = new Intent(context, NewActivity.class);
     i.putExtra("txt_value",txt_value);
     startActivity(i);
  }
}

Upvotes: 0

Bubu
Bubu

Reputation: 1543

In your 2nd activity, replace :

String pokemon = getIntent().getExtras().getString("pokemonName");

by :

String pokemon = getIntent().getStringExtra("pokemonName");

Explication : In your first activity, you pass a String in the Intent, so you must retrieve it by getIntent().getStringExtra.

getIntent().getExtras() return a Bundle passed with :

Bundle b = new Bundle();
b.putString("key", "value"); // put String into the Bundle, not the Intent
intent.putExtras(b); // Put the Bundle into the Intent

Upvotes: 0

Related Questions