super.onActivityResult inside adapter class? Android

Slim C. picture Slim C. · Dec 17, 2015 · Viewed 19.8k times · Source

I have RecyclerView with very complex item, multiple buttons/images/texts. To access each button/image I set my click Listeners inside my Adapter class.

But now I am trying add function to set contact ringtone and I have a problem.

I am calling the onActivityResult method like this:

Intent contactIntent = new Intent(Intent.ACTION_PICK);
                contactIntent.setType(ContactsContract.Contacts.CONTENT_TYPE);
                contactIntent.putExtra("ITEM_POSITION", position);
                ((Activity) context).startActivityForResult(contactIntent, CONTACT_CHOOSER_ACTIVITY_CODE );

and that works fine. But here is the problem:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {
....
...
...
}
}

I get this error: Cannot resolve method 'onActivityResult(int, int, android.content.Intent)' Is there any way to avoid this? or is it possible to have this method inside adapter class? If not what should I do?

Answer

kandroidj picture kandroidj · Dec 17, 2015

You cannot have this in any Adapter class, this is only a method inside Activity, each class that extends Activity will be able to Override this method but certainly not an Adapter.

Please see Overrides in java

And for onActivityResult please see Activity#onActivityResult(int, int, Intent)

For something like a RecyclerView.Adapter you are going to want to define an interface in your adapter and implement that interface in your Activity.

For example here is code for an application that sends a String of the Item clicked and its position to a new Activity which displays it:

MainActivity:

public class MainActivity extends AppCompatActivity implements MyAdapter.CallbackInterface {


    private static final int MY_REQUEST = 1001;

    private static final String [] ITEMS = {"Item 1", "Item 2", "Item 3" ,"Item 4", "Item 5", "Item 6"};

    private MyAdapter myAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ... Adapter setup, simple LinearLayoutManager and String [] used
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rec_view);
        myAdapter = new MyAdapter(this, ITEMS);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(myAdapter);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch(resultCode){

            case RESULT_OK:

                // ... Check for some data from the intent
                if(requestCode == MY_REQUEST){
                    // .. lets toast again
                    int position = -1;
                    if(data != null){
                        position = data.getIntExtra("Position", 0);
                    }

                    if(position != -1) {
                        Toast.makeText(this, "Handled the result successfully at position " + position, Toast.LENGTH_SHORT).show();
                    }else{
                        Toast.makeText(this, "Failed to get data from intent" , Toast.LENGTH_SHORT).show();
                    }
                }

                break;

            case RESULT_CANCELED:

                // ... Handle this situation
                break;
        }
    }

    /**
     * Interface Method which communicates to the Acitivty here from the {@link MyAdapter}
     * @param position - the position
     * @param text - the text to pass back
     */
    @Override
    public void onHandleSelection(int position, String text) {

        Toast.makeText(this, "Selected item in list "+ position + " with text "+ text, Toast.LENGTH_SHORT).show();

        // ... Start a new Activity here and pass the values
        Intent secondActivity = new Intent(MainActivity.this, DetailActivity.class);
        secondActivity.putExtra("Text",text);
        secondActivity.putExtra("Position", position);
        startActivityForResult(secondActivity, MY_REQUEST);
    }
}

xml for MainActivity:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.divshark.recyclerviewsimpledemo.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/rec_view" />
</RelativeLayout>

MyAdapter:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder>{

    private CallbackInterface mCallback;
    private String [] mMyItems;
    private Context mContext;

    public interface CallbackInterface{

        /**
         * Callback invoked when clicked
         * @param position - the position
         * @param text - the text to pass back
         */
        void onHandleSelection(int position, String text);
    }

    public MyAdapter(Context context, String [] myItems){

        mContext = context;
        mMyItems = myItems;

        // .. Attach the interface
        try{
            mCallback = (CallbackInterface) context;
        }catch(ClassCastException ex){
            //.. should log the error or throw and exception
            Log.e("MyAdapter","Must implement the CallbackInterface in the Activity", ex);
        }
    }

    @Override
    public int getItemCount() {
        return mMyItems.length;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

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

        // Set the text for the View
        holder.mTextView.setText(mMyItems[position]);

        // Use your listener to pass back the data
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mCallback != null){
                    mCallback.onHandleSelection(position, mMyItems[position]);
                }
            }
        });
    }

    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false);
        return new MyHolder(view);
    }

    static class MyHolder extends RecyclerView.ViewHolder{

        TextView mTextView;

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

            mTextView = (TextView) itemView.findViewById(R.id.tv_list_item);
        }
    }
}

layout for the Adapter:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="?listPreferredItemHeight">

    <TextView
        android:id="@+id/tv_list_item"
        android:textColor="@android:color/black"
        tools:text="Some Text Holder"
        android:layout_marginLeft="16dp"
        android:textSize="18sp"
        android:layout_centerVertical="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</RelativeLayout>

and the DetailActivity:

public class DetailActivity extends AppCompatActivity {

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

        TextView textView = (TextView) findViewById(R.id.tv_detail_text);

        if(getIntent() != null && getIntent().getExtras() != null) {
            Bundle extras = getIntent().getExtras();
            String text = extras.getString("Text");
            int position = extras.getInt("Position");

            textView.setText(String.format("%s at position %d", text, position));

            // .. For this purpose set result okay and use position as part of data when Activity finishes
            // Which will in turn invoke the onActivityResult method in the calling activity
            Intent resultIntent = new Intent();
            resultIntent.putExtra("Position", position);
            setResult(RESULT_OK, resultIntent);
        }
    }
}

layout for Detail activity:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">


    <TextView
        android:id="@+id/tv_detail_text"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</FrameLayout>

Good luck and happy coding!