RecyclerView в Android гаснет при нажатии кнопки сортировки из другого действия - PullRequest
1 голос
/ 04 октября 2019

Хорошо, поэтому я пытаюсь отсортировать recyclerView, инициализированный в начале, из XML. Когда я запускаю приложение, я вижу электронные письма, а также нажимаю на них. Кнопка для сортировки находится в разделе «Настройки», но всякий раз, когда я возвращаюсь к своему основному виду деятельности, где находится мой RecyclerView, после нажатия этой кнопки, мой recyclerView становится пустым.

Вот мой MainActivity

package com.example.assignment_1;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    //Variables
    private ArrayList<String> mNames = new ArrayList<>();
    private ArrayList<String> mImageurls = new ArrayList<>();
    private ArrayList<String> mHeaders = new ArrayList<>();
    private ArrayList<String> mContent = new ArrayList<>();
    static ArrayList<AssignmentEmail> emails = new ArrayList<>();
    private RecyclerViewAdapdter adapter;
    private RecyclerView recyclerView;
    private Context mContext;

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

        EmailProvider emailProvider = new EmailProvider();
        Context context = getApplicationContext();
        if(emails.isEmpty() == true){
            emails = emailProvider.getEmails(context);
            loadEmails();
        }
    }

    private void loadEmails(){
        Log.d(TAG, "loadEmails: initBitmaps Called");
        for(int i = 0; i < emails.size(); i++) {
            mImageurls.add("@drawable/e1.jpg");
            mNames.add(emails.get(i).getAuthor());
            mHeaders.add(emails.get(i).getTitle());
            mContent.add(emails.get(i).getBody());
        }
        initRecyclerView();
    }

    public static ArrayList<AssignmentEmail> getEmails(){
        return emails;
    }

    public void sortEmails(ArrayList<AssignmentEmail> arrayOfEmails){
        Comparator<AssignmentEmail> compareByAuthor = (AssignmentEmail o1, AssignmentEmail o2) -> o1.getAuthor().compareTo( o2.getAuthor());
        Collections.sort(arrayOfEmails, compareByAuthor);
        mImageurls.clear();
        mNames.clear();
        mHeaders.clear();
        mContent.clear();
        for(int i = 0; i < arrayOfEmails.size(); i++) {
            mImageurls.add("@drawable/e1.jpg");
            mNames.add(arrayOfEmails.get(i).getAuthor());
            mHeaders.add(arrayOfEmails.get(i).getTitle());
            mContent.add(arrayOfEmails.get(i).getBody());
        }
        adapter = new RecyclerViewAdapdter(mImageurls,mNames,mHeaders,mContent,this);
        adapter.notifyDataSetChanged();
    }

    private void initRecyclerView(){
        Log.d(TAG, "initRecyclerView: init RecyclerView");
        recyclerView  = findViewById(R.id.recyclerview);
        adapter = new RecyclerViewAdapdter(mImageurls,mNames,mHeaders,mContent,this);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate activity menu items.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item){
        int id = item.getItemId();

        if (id == R.id.action_settings){
            Intent intent = new Intent(getApplicationContext(), Settings.class);
            startActivity(intent);
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Вот мой RecyclerViewAdapter

package com.example.assignment_1;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import de.hdodenhof.circleimageview.CircleImageView;

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

    private static final String TAG = "RecyclerViewAdapter";
    private ArrayList<String> mImages = new ArrayList<>();
    private ArrayList<String> mEmailTitle = new ArrayList<>();
    private ArrayList<String> mEmailHeader = new ArrayList<>();
    private ArrayList<String> mEmailContent = new ArrayList<>();
    private Context mContext;

    public RecyclerViewAdapdter(ArrayList<String> mImages, ArrayList<String> mEmailTitle, ArrayList<String> mEmailHeader, ArrayList<String> mEmailContent, Context mContext) {
        this.mImages = mImages;
        this.mEmailTitle = mEmailTitle;
        this.mEmailHeader = mEmailHeader;
        this.mEmailContent = mEmailContent;
        this.mContext = mContext;
    }

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

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
        Log.d(TAG, "onBindViewHolder: Called");

        Glide.with(mContext)
                .asBitmap()
                .load(mImages.get(position))
                .into(holder.Image);

        holder.email_from.setText(mEmailTitle.get(position));
        holder.email_header.setText(mEmailHeader.get(position));
        holder.email_contents.setText(mEmailContent.get(position));
        holder.Email_interface.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Log.d(TAG, "onClick: Email Clicked");
                //Toast.makeText(mContext, mEmailTitle.get(position),Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(mContext.getApplicationContext(), LayoutItemsActivity.class);
                intent.putExtra("EmailFrom",mEmailTitle.get(position));
                intent.putExtra("EmailHeader",mEmailHeader.get(position));
                intent.putExtra(("EmailContents"),mEmailContent.get(position));
                mContext.startActivity(intent);
            }
        });
    }

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


    public class ViewHolder extends RecyclerView.ViewHolder{

        CircleImageView Image;
        TextView email_from;
        TextView email_header;
        TextView email_contents;
        RelativeLayout Email_interface;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            Image = itemView.findViewById(R.id.image);
            email_from = itemView.findViewById(R.id.EmailFrom);
            email_header = itemView.findViewById(R.id.EmailHeader);
            email_contents = itemView.findViewById(R.id.EmailContents);
            Email_interface = itemView.findViewById(R.id.email_interface);
        }
    }
}

Вот где находится моя кнопка


package com.example.assignment_1;

import android.content.Intent;
import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.view.View;
import android.widget.Button;

import java.util.ArrayList;

public class Settings extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        Button resetButton = findViewById(R.id.button2);
        resetButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                MainActivity mainActivity = new MainActivity();
                ArrayList<AssignmentEmail> emailArray = mainActivity.getEmails();
                mainActivity.sortEmails(emailArray);
            }
        });
    }

}

Ответы [ 3 ]

1 голос
/ 04 октября 2019

С вашего MainActivity вызовите Settings, используя startActivityForResult() метод

Например:

    if (id == R.id.action_settings){
        Intent intent = new Intent(getApplicationContext(), Settings.class);
        startActivityForResult(intent,1);
        return true;
    }

В вашем Settings Activity установите данные, которые вы хотите вернуть обратнодо MainActivity. Если вы не хотите возвращаться назад, не устанавливайте ничего.

resetButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent returnIntent = new Intent();
                setResult(Activity.RESULT_OK,returnIntent);
                finish();
            }
        });

Теперь у вас main activity вы должны написать следующий код для метода onActivityResult().

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

    if (requestCode == 1) {
        if(resultCode == Activity.RESULT_OK){
            // here you can sorting your recyclerview
            sortEmails(getEmails());
        }
        if (resultCode == Activity.RESULT_CANCELED) {
            //Write your code if there's no result
        }
    }
}

Другой способ

Если вы не хотите прекратить действие setting activity после нажатия resetbutton, тогда вы можете использовать shared preference.

Пример

public class SharedPrefManager{
  private static SessionManager jInstance;
  private final SharedPreferences prefs;
  private final SharedPreferences.Editor editor;

  // private constructor to force use of 
  // getInstance() to create Singleton object 
  private SharedPrefManager(Context context) {
      prefs = context.getSharedPreferences("Your_Preference_name", Context.MODE_PRIVATE);
      editor = prefs.edit();
  }

  // create the instance when it is accessed for the first time
  public static synchronized SharedPrefManager getInstance(Context context) {
      if (jInstance != null) {
          return jInstance;
      } else {
          jInstance = new SharedPrefManager(context);
          return jInstance;
      }
  }


  public void isSortedByEmail(boolean emailSorting){
      editor.putString("emailSorting",emailSorting);
      editor.apply();
  }


  public boolean isSortedByEmail(){
      return prefs.getBoolean("emailSorting",false);
  }
}

В вашем setting activity вы должны сделать, как показано ниже

resetButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
      SharedPrefManager.getInstance(context).isSortedByEmail(true);
    }
});

И в вашем main activity внутри вашего onStart()

@Override
protected void onStart(){
   super.onStart();
   if(SharedPrefManager.getInstance(context).isSortedByEmail()){
     // here you can sorting your recyclerview
     sortEmails(getEmails());
   }
}

Надеюсь, это поможет вам. Счастливое кодирование

1 голос
/ 04 октября 2019

Если вы все еще хотите обновить представление переработчика при настройке активности, используйте эту библиотеку.

https://github.com/greenrobot/EventBus

Ссылка для реализации

https://stackoverflow.com/a/40987755/6452937

Вы не можете общаться между действиями, как вы упомянули.

0 голосов
/ 04 октября 2019

Вы инициализировали MainActivity в настройках, но эта ссылка отличается от вашей фактической MainActivity, которая отображается. Я обнаружил некоторые другие проблемы, связанные с наборами данных в адаптере, которые необходимо улучшить. После этого вам нужно найти способ, с помощью которого вы можете отправить информацию фильтра от Settings до MainActivity. Есть несколько способов, но я бы порекомендовал вам использовать SharedPreference в вашем случае.

В Settings вы должны установить настройки фильтра в SharedPreference и получить их значения в MainActivity

public class Settings extends AppCompatActivity {

    SharedPreferences.Editor editSettings;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        editSettings = getSharedPreferences("filter", Context.MODE_PRIVATE).edit();
        resetButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                editSettings.putBoolean("reset", true).apply();
            }
        });
    }
}

В Adapter внесите следующие изменения,

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

    private static final String TAG = "RecyclerViewAdapter";
    private ArrayList<String> mImages = new ArrayList<>();
    private ArrayList<String> mEmailTitle = new ArrayList<>();
    private ArrayList<String> mEmailHeader = new ArrayList<>();
    private ArrayList<String> mEmailContent = new ArrayList<>();
    private Context mContext;

    public RecyclerViewAdapdter(Context mContext) {
        this.mContext = mContext;
    }

    public void submitData((ArrayList<String> mImages, ArrayList<String> mEmailTitle, ArrayList<String> mEmailHeader, ArrayList<String> mEmailContent) {
        this.mImages.clear();
        this.mEmailTitle.clear();
        this.mEmailHeader.clear();
        this.mEmailContent.clear();

        this.mImages.addAll(mImages);
        this.mEmailTitle.addAll(mEmailTitle);
        this.mEmailHeader.addAll(mEmailHeader);
        this.mEmailContent.addAll(mEmailContent);

        notifyDataSetChanged()
    }

    ...
}

В MainActivity переопределите onResume() и обновите список, если значение из SharedPreference равно true,

public class MainActivity extends AppCompatActivity {

    ...

    SharedPreferences spSettings;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        spSettings = getSharedPreferences("filter", Context.MODE_PRIVATE);

        ...
    }

    @Override
    protected void onResume() {
        super.onResume();
        boolean reset = spSettings.getBoolean("reset", false);
        if(reset) {
            ArrayList<AssignmentEmail> emailArray = getEmails();
            sortEmails(emailArray);
        }
    }

    private void initRecyclerView(){
        ...

        adapter = new RecyclerViewAdapdter(mContent,this);
        adapter.submitData(mImageurls,mNames,mHeaders);

        ...
    }

    public void sortEmails(ArrayList<AssignmentEmail> arrayOfEmails){
        ...

        adapter.submitData(mImageurls,mNames,mHeaders,mContent);
    }

}
...