super.onActivityResult inside adapter class? Android

匿名 (未验证) 提交于 2019-12-03 01:49:02

问题:

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("RINGTONE_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?

回答1:

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:

MyAdapter:

public class MyAdapter extends RecyclerView.Adapter{      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:

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:

Good luck and happy coding!



回答2:

Another solution is to set onActivityResult method in activity class where you initiate your RecyclerView/ListView. That works too, except for some reason I got NPE errors when I tried to pass data using intents, so work-arround for that is create static String/Int and change it's value on clicks and access. That works just fine. But the answer above is also great, and it works just as fine, perhaps even better, performance wise.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!