androidonactivityresult

super.onActivityResult inside adapter class? Android


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?


Solution

  • 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!