На itemclick переработчикаПросмотреть - PullRequest
0 голосов
/ 30 апреля 2020

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

Я хочу добавить разные данные в каждый список предметов. но это не происходит для каждого списка элементов, которые сохраняются в действии те же самые сохраненные данные ....

есть ли какое-либо решение ..

это второе действие ..

 protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.student_list);

    loadData();

    toolbar = findViewById(R.id.toolbar);

    bundle = getIntent().getExtras();
    String subName = bundle.getString("Subject Name");

    if (bundle != null) {
        toolbar.setTitle(subName);
    }

    fabButton();
    buildRecyclerView();
}

private void buildRecyclerView() {

    recyclerView = findViewById(R.id.recyclerView2);
    recyclerView.hasFixedSize();
    layoutManager = new LinearLayoutManager(StudentListActivity.this);
    rAdapter = new AdapterForStudentList(listOfNames);

    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setAdapter(rAdapter);

    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallback);
    itemTouchHelper.attachToRecyclerView(recyclerView);

}

public void insertData(String text, String t1, String t2) {
    ListOfNames lt = new ListOfNames(text, t1, t2);
    listOfNames.add(lt);
    rAdapter.notifyDataSetChanged();

}

public void saveData() {
    sharedPreferences = getSharedPreferences("SHARED PREF", MODE_PRIVATE);
    editor = sharedPreferences.edit();

    Gson gson = new Gson();
    String json = gson.toJson(listOfNames);

    editor.putString("text", json);
    editor.apply();
}

public void loadData() {


    sharedPreferences = getSharedPreferences("SHARED PREF", MODE_PRIVATE);

    Gson gson = new Gson();
    String json = sharedPreferences.getString("text", null);
    Type type = new TypeToken<ArrayList<ListOfNames>>() {
    }.getType();

    listOfNames = gson.fromJson(json, type);

    if (listOfNames == null) {
        listOfNames = new ArrayList<>();
    }
}

ListOfNames deletedItem = null;
ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        return false;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        final int position = viewHolder.getAdapterPosition();
        String name = listOfNames.get(position).getStudentName();

        deletedItem = listOfNames.get(position);
        listOfNames.remove(deletedItem);

        sharedPreferences = getSharedPreferences("SHARED PREF", MODE_PRIVATE);
        editor = sharedPreferences.edit();
        editor.remove("text");


        saveData();
        editor.apply();
        rAdapter.notifyItemRemoved(position);

        Snackbar.make(recyclerView, name + "Deleted", Snackbar.LENGTH_LONG)
                .setAction("Undo", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        listOfNames.add(position, deletedItem);
                        rAdapter.notifyItemInserted(position);

                        saveData();
                    }
                }).show();
    }

    @Override
    public void onChildDrawOver(@NonNull Canvas c, @NonNull RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        new RecyclerViewSwipeDecorator.Builder(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)

                .addSwipeLeftBackgroundColor(ContextCompat.getColor(StudentListActivity.this, R.color.my_background))
                .addSwipeLeftActionIcon(R.drawable.ic_delete_black_24dp)
                .create()
                .decorate();
        super.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);

    }
};

public void fabButton() {
    FloatingActionButton floatingActionButton = findViewById(R.id.fab2);
    floatingActionButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AlertDialog.Builder b = new AlertDialog.Builder(StudentListActivity.this);
            View view = getLayoutInflater().inflate(R.layout.dialogbox_frontpage, null);

            final EditText editText = view.findViewById(R.id.editText);
            b.setView(view);
            b.setTitle("Student name");
            b.setPositiveButton("ok", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    String text = editText.getText().toString();

                    if (text.isEmpty()) {
                        Toast.makeText(StudentListActivity.this, "Please add subject name", Toast.LENGTH_SHORT).show();
                    } else {
                        insertData(text, t1, t2);
                        saveData();
                    }
                }
            });
            b.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
            b.setCancelable(false);
            b.show();
        }
    });
}

}

**MainActivity**

`public class ScrollingActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private AdaptreForRecycler adapter;
private RecyclerView.LayoutManager layoutManager;
private ArrayList<ExampleItem> mExampleList;
RecyclerView.ViewHolder viewHolder;


private Gson gson;
private String json;
private Type type;

private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;


EditText editText;
private ExampleItem ex;
public static final String t2 = "new";



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


    loadData();
    buildRecyclerView();

    editText = findViewById(R.id.editText);
    fabButoonClick();


}

public void saveData() {

    sharedPreferences = getSharedPreferences("SHARED_PREFS", MODE_PRIVATE);
    editor = sharedPreferences.edit();
    gson = new Gson();
    json = gson.toJson(mExampleList);

    editor.putString("text", json);
    editor.apply();

}

public void loadData() {

    sharedPreferences = getSharedPreferences("SHARED_PREFS", MODE_PRIVATE);
    gson = new Gson();
    json = sharedPreferences.getString("text", null);
    type = new TypeToken<ArrayList<ExampleItem>>() {
    }.getType();
    mExampleList = gson.fromJson(json, type);

    if (mExampleList == null) {
        mExampleList = new ArrayList<>();
    }

}


public void insertItem(String text, String t2) {

    ex = new ExampleItem(text, t2);
    mExampleList.add(ex);
    adapter.notifyDataSetChanged();


}

ExampleItem deletedIndex = null;
ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        return false;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        final int position = viewHolder.getAdapterPosition();
        String name = mExampleList.get(position).getText1();
        deletedIndex = (mExampleList.get(position));
        mExampleList.remove(position);

        sharedPreferences = getSharedPreferences("SHARED_PREFS", MODE_PRIVATE);
        editor = sharedPreferences.edit();
        editor.remove("text");

        saveData();

        editor.apply();
        adapter.notifyItemRemoved(position);

        Snackbar.make(recyclerView, name + " Deleted", Snackbar.LENGTH_LONG)
                .setAction("Undo", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mExampleList.add(position, deletedIndex);
                        adapter.notifyItemInserted(position);

                        saveData();

                    }
                }).show();
    }

    @Override
    public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {

        new RecyclerViewSwipeDecorator.Builder(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)

                .addSwipeLeftBackgroundColor(ContextCompat.getColor(ScrollingActivity.this, R.color.my_background))
                .addSwipeLeftActionIcon(R.drawable.ic_delete_black_24dp)
                .create()
                .decorate();
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }
};


private void buildRecyclerView() {
    recyclerView = findViewById(R.id.recyclerView);
    recyclerView.setHasFixedSize(true);
    layoutManager = new LinearLayoutManager(ScrollingActivity.this);
    adapter = new AdaptreForRecycler(mExampleList);

    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setAdapter(adapter);

    adapter.setOnItemClickListener(new AdaptreForRecycler.OnItemCLickListener() {
        @Override
        public void onItemClick(int position) {


            Intent i =new Intent(ScrollingActivity.this,StudentListActivity.class);
            i.putExtra("Subject Name",mExampleList.get(position).getText1());

            startActivity(i);
        }
    });

    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallback);
    itemTouchHelper.attachToRecyclerView(recyclerView);
}

public void fabButoonClick() {
    FloatingActionButton fab = findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            AlertDialog.Builder b = new AlertDialog.Builder(ScrollingActivity.this);
            View mview = getLayoutInflater().inflate(R.layout.dialogbox_frontpage, null);

            final EditText editText = mview.findViewById(R.id.editText);
            b.setView(mview);
            b.setTitle("Add subject name");
            b.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });

            b.setPositiveButton("ok", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    String text = editText.getText().toString();

                    if (text.isEmpty()) {
                        Toast.makeText(ScrollingActivity.this, "Please add subject name", Toast.LENGTH_SHORT).show();
                    } else {

                        insertItem(text, t2);

                        saveData();
                    }
                }
            });
            b.setCancelable(false);
            b.show();
        }
    });

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.menu_scrolling, menu);

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();


    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

} AdaptreOfFirstActivity`

public class AdaptreForRecycler extends RecyclerView.Adapter<AdaptreForRecycler.ProgrammingViewHolder> {

private OnItemCLickListener mListener;

public interface OnItemCLickListener {
    void onItemClick(int position);
}

public void setOnItemClickListener(OnItemCLickListener listener) {
    mListener = listener;
}

private ArrayList<ExampleItem> mExampleList;

public class ProgrammingViewHolder extends RecyclerView.ViewHolder {

    public TextView mTextView1, mTextView2;

    public ProgrammingViewHolder(@NonNull View itemView, final OnItemCLickListener listener) {
        super(itemView);

        mTextView1 = itemView.findViewById(R.id.tv1);
        mTextView2 = itemView.findViewById(R.id.tv2);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null) {
                    int position = getAdapterPosition();
                    if (position != RecyclerView.NO_POSITION)
                        listener.onItemClick(position);
                }
            }
        });

    }
}

public AdaptreForRecycler(ArrayList<ExampleItem> exampleList) {

    mExampleList = exampleList;
}

@NonNull
@Override
public AdaptreForRecycler.ProgrammingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View view = inflater.inflate(R.layout.list_item_layout, parent, false);
    return new ProgrammingViewHolder(view, mListener);

}

@Override
public void onBindViewHolder(@NonNull AdaptreForRecycler.ProgrammingViewHolder holder, int position) {

    ExampleItem currentItem = mExampleList.get(position);
    holder.mTextView1.setText(currentItem.getText1());
    holder.mTextView2.setText(currentItem.getText2());
}


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

} AdaptreForSecondActivity

public class AdapterForStudentList extends RecyclerView.Adapter<AdapterForStudentList.StudentViewHolder> {


private ArrayList<ListOfNames> mListOfNames;

public static class StudentViewHolder extends RecyclerView.ViewHolder {
    public TextView studentName, attendence, percentage;

    public StudentViewHolder(@NonNull View itemView) {
        super(itemView);
        studentName = itemView.findViewById(R.id.studentName);
        attendence = itemView.findViewById(R.id.attendence);
        percentage = itemView.findViewById(R.id.percentage);


    }
}

public AdapterForStudentList(ArrayList<ListOfNames> listOfNames) {

    mListOfNames = listOfNames;
}

@NonNull
@Override
public StudentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View view = inflater.inflate(R.layout.check_box_cardview, parent, false);

    return new StudentViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull StudentViewHolder holder, int position) {

    ListOfNames currentItems = mListOfNames.get(position);
    holder.studentName.setText(currentItems.getStudentName());
    holder.attendence.setText(currentItems.getAttendent());
    holder.percentage.setText(currentItems.getPercetage());
}

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

}

1 Ответ

0 голосов
/ 30 апреля 2020

Теперь я увидел, что вы сделали то, что я сказал в моем первом оригинальном ответе, я благодарю вас за это.

Кроме того, эта тема / сообщение может закончиться, поскольку вы уже реализовали onClick для RecyclerView. Буду признателен, если вы отметите мой ответ как решение.

Но, конечно, вы подняли еще одну проблему:

Я хочу добавить разные данные в каждый список элементов. но это происходит не для каждого списка элементов, которые загружаются в упражнении одинаковыми сохраненными данными ...

Это потому, что вы загружаете, а также сохраняете с помощью того же ключа :

editor.putString("text", json);
editor.apply();

Видите? Вы загружали и сохраняли на ключ "text" в каждой теме. (Вы упомянули, что у вас есть список предметов, поэтому я использовал слово subject )

Я предлагаю вам создать средство для изменения ключа для каждого отдельного предмета. В этом случае имя вашего субъекта может быть ключевым вместо простого "text".

. Я также предлагаю вам использовать переменную private static final String для "text", а также сделать ее более понятной. Ключ под названием "text" немного двусмысленен, не правда ли?

Теперь я опубликую часть измененного кода вашего StudentListActivity, я призываю вас проанализировать его и вставить в свой код. Я уверен, что теперь это будет работать.

Модифицированная часть в StudentListActivity

// Added a string variable here as key for saving/loading your data
String subName; // I kept your naming the same which is 'subName'

protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.student_list);

    // I placed this bit of code above loadData() now that we
    // use subName as the key
    // Or else loadData() will use the initial value of
    // subName which is going to be null first
    bundle = getIntent().getExtras();
    subName = bundle.getString("Subject Name");

    if (bundle != null) {
        toolbar.setTitle(subName);setTitle(subName);
    }

    loadData();

    toolbar = findViewById(R.id.toolbar);

    fabButton();
    buildRecyclerView();
}

// Other code... Which in your code are:
// private void buildRecyclerView() { ... }
// public void insertData(String text, String t1, String t2) { ... }

public void saveData() {
    sharedPreferences = getSharedPreferences("SHARED PREF", MODE_PRIVATE);
    editor = sharedPreferences.edit();

    Gson gson = new Gson();
    String json = gson.toJson(listOfNames);

    // Now here use the name of your subject as key
    // Which is of course the variable 'subName'
    editor.putString(subName, json);
    editor.apply();
}

public void loadData() {


    sharedPreferences = getSharedPreferences("SHARED PREF", MODE_PRIVATE);

    Gson gson = new Gson();
    // Same here
    // Use 'subName' as key
    String json = sharedPreferences.getString(subName, null);
    Type type = new TypeToken<ArrayList<ListOfNames>>() {
    }.getType();

    listOfNames = gson.fromJson(json, type);

    if (listOfNames == null) {
        listOfNames = new ArrayList<>();
    }
}

// Other code ...

Кстати, я попытался сделать макеты самостоятельно, чтобы протестировать ваше приложение и я кое-что заметил: я думаю, у вас есть EditText внутри вашего dialogbox_frontpage. xml файла. И вы все еще написали код, чтобы получить представление к вашему ScrollingActivity, который не нужен. Фактически, вы переопределили его в методе onClick. Вы можете удалить эту переменную global.

Последние примечания: Это всего лишь предложение, но вы можете попробовать и изучить шаблон Singleton. Используйте этот шаблон для сохранения ваших данных. Кроме того, SharedPreferences не очень хорошая идея, чтобы сохранить огромное количество данных. Поэтому я также призываю вас попытаться найти базы данных Room .

Я надеюсь, что ваша программа работает сейчас и, как всегда, удачного кодирования! (Это был очень длинный ответ, хахаха)


Оригинальный ответ (немного его изменил)

Я предлагаю создать interface, который будет передать позицию элемента, по которому щелкнули, потому что мы заботимся только о позиции элемента, чтобы иметь возможность что-то с ним сделать. Кроме того, так лучше, чтобы мы могли добавить в действие код, который будет выполняться при нажатии на элемент.

Вот как должен выглядеть interface:

public interface OnItemClickListener {
    void onItemClick(int position);
}

Добавьте новый variable внутри вашего adapter, то есть OnItemClickListener:

private OnItemCLickListener listener;

Вы можете либо определить его реализацию, внедрив его в действие, либо передать его реализацию, создав другой метод с именем addOnItemClickListener в вашем adapter:

addOnItemClickListener(OnItemClickListener listener) {
    this.listener = listener;
}

Затем внутри вашего метода onBindViewHolder получите макет элемента из ViewHolder, установите его слушатель onClick и, наконец, внутри метод onClick, вызовите метод вашего интерфейса onItemClick внутри него и передайте позицию там. Вот так:

@Override
public void onBindViewHolder(@NonNull CustomRecyclerView.ViewHolder holder, final int position) {
    holder.layout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            listener.onItemClick(position);
        }
    });
}



Редактировать: Объяснение, почему я устанавливаю слушателя внутри метода onBindViewHolder

itemView или View, которые мы получаем от конструктора ViewHolder , зависит от View, возвращаемого LayoutInflater внутри вашего onCreateViewHolder. Следовательно, ресурс макета, который вы передаете в методе inflate, независимо от того, какой основной макет вы там используете (например, ConstraintLayout, LinearLayout, это также может быть TextView, Button, et c.), Будет возвращено View. Чтобы проверить это, попробуйте скопировать / вставить эту простую строку кода в onCreateViewHolder, затем запустите ваше приложение и проверьте Logcat:

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(context).inflate(R.layout.YOUR_LAYOUT_HERE, parent, false);
    Log.i("View", view.getClass().getSimpleName()); // Logs the main view in our layout
    return new YourCustomViewHolderHere(view);
}

ViewHolder только отвечает за получение наших представлений, потому что использование метода findViewById является сложной задачей, если мы делаем это внутри onBindViewHolder, поэтому мы не делаем это там, потому что это замедлит производительность нашего приложения.

Мы выполняем все настройки, такие как, например, изменение текста TextViews или установка onClick слушателей внутри onBindViewHolder, чтобы избежать создания ненужной сложности в нашем коде. Мы не хотим, чтобы коды плавали вокруг, не так ли?

Кроме того, шаблон Observer весьма опасен .

Был разговор на конференции Android Я не помню, о чем говорилось RecyclerView. Вы знаете, почему это так называется? Потому что это повторяет просмотров. (Требуется правильное объяснение того, как они перерабатывают представления, поэтому я не буду освещать это здесь. Я думаю, что вы можете найти его на YouTube, если будете искать "Android Conference RecyclerView" , это довольно долго, может быть, около часа, но это стоит посмотреть.)

Шаблон Observer (т. е. Listener) может вызвать утечки памяти, что повлияет на производительность нашего приложения. Следовательно, лучше установить его в нашем методе onBindViewHolder, потому что всякий раз, когда мы прокручиваем вниз или вверх по нашему RecyclerView, он перезапускает представления, и мы рискуем при создании множественных экземпляры того же слушателя внутри ViewHolder.

Согласно Википедии о Шаблон наблюдателя :

Шаблон наблюдателя может вызвать утечки памяти, известные как проблема потерянного слушателя, потому что в реализации basi c она требует как явной регистрации, так и явной отмены регистрации, как в шаблоне dispose, потому что субъект держит сильные ссылки на наблюдателей, сохраняя их живыми. Это может быть предотвращено тем, что субъект держит слабые ссылки на наблюдателей.

Другой способ установить onClick находится внутри onCreateViewHolder, но выгода в том, что у вас нет способа узнать, какие элемент был нажат.

Надеюсь, это ответит на ваш вопрос в комментарии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...