Android. Добавляем в избранное

В одном из разрабатываемых мною приложениях, нужно было добавить возможность добавления материала в избранное. Кнопка добавления в избранное должна изменять свой внешний вид, в зависимости от того, находится элемент в избранном или нет. Следовательно у нас есть всего два положения: true и false. Кроме того, пользователь должен иметь возможность добавлять элементы в избранное не только из списка, но на экране с материалом.

Задача

Для примера я возьму список с уроками. У нас есть два экрана: это, собственно, сам список с заголовками и экран с просмотром полного текста урока.

Подготовка

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

public class Lesson {

	String title;
	String text;
	boolean favorite;

	public Lesson(String title, String text) {
		this.title = title;
		this.text = text;
	}

	public void setFavorite(boolean favorite) {
		this.favorite = favorite;
	}

	public boolean isFavorite() {
		return favorite;
	}
}

Теперь, создадим ArrayList и заполним его данными:

ArrayList<Lesson> lessonsList;

@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);

	lessonsList = new ArrayList<Lesson>();

	for (int i = 0; i < 10; i++) {
		lessonsList.add(new Lesson("Урок " + i, "Текст от урока номер " + i+ ". В этом уроке мы научимся ..."));
	}

}

Создадим адаптер:

public class LessonListAdapter extends BaseAdapter {

	private Context context;
	private ArrayList<Lesson> lessonsList;
	private LayoutInflater inflater;

	public LessonListAdapter(Context context, ArrayList<Lesson> lessonsList) {
		this.context = context;
		this.lessonsList = lessonsList;
		inflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}

	@Override
	public int getCount() {

		return lessonsList.size();
	}

	@Override
	public Lesson getItem(int position) {

		return lessonsList.get(position);
	}

	@Override
	public long getItemId(int position) {

		return position;
	}

	@Override
	public View getView(int position, View v, ViewGroup parent) {
		View view = null;
		ViewHolder viewHolder;

		if (v == null) {
			viewHolder = new ViewHolder();
			view = inflater.inflate(R.layout.lesson_item, parent, false);
			viewHolder.tvLessonName = (TextView) view
					.findViewById(R.id.tvLessonItem);
			viewHolder.chbFaforiteLesson = (CheckBox) view
					.findViewById(R.id.chbFavoriteLesson);
			viewHolder.tvLessonName.setOnClickListener(onClick);
			viewHolder.chbFaforiteLesson.setOnClickListener(onClick);
			view.setTag(viewHolder);
		} else {
			view = v;
			viewHolder = (ViewHolder) view.getTag();
		}
		Lesson lesson = lessonsList.get(position);

		viewHolder.tvLessonName.setTag(position);
		viewHolder.chbFaforiteLesson.setTag(position);

		viewHolder.tvLessonName.setText(lesson.getTitle());
		viewHolder.chbFaforiteLesson.setChecked(lesson.isFavorite());

		return view;
	}

	static class ViewHolder {
		private TextView tvLessonName;
		private CheckBox chbFaforiteLesson;
	}

	OnClickListener onClick = new OnClickListener() {

		@Override
		public void onClick(View view) {
			switch (view.getId()) {
			case R.id.tvLessonItem:
				Intent intent = new Intent(context, LessonActivity.class);
				intent.putExtra("position", (Integer) view.getTag());
				context.startActivity(intent);
				break;

			case R.id.chbFavoriteLesson:
				lessonsList.get((Integer) view.getTag()).setFavorite(
						((CheckBox) view).isChecked());
				break;
			}

		}

	};

}

Список с уроками

View-элементам мы присваиваем позицию в качестве тега. В OnClickListener’е мы вытаскиваем тег из View и таким образом узнаем на какой пункт нажал пользователь. Также мы использовали паттерн ViewHolder, который позволяет оптимизировать работу ListView.При нажатии на TextView открывается LessonActivity. В Intent мы передаем позицию урока в списке.

Файл /layout/main.xml:

<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"
    tools:context="${relativePackage}.${activityClass}" >

    <ListView
        android:id="@+id/lessonList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="#cccccc"
        android:dividerHeight="1px" />

</RelativeLayout>

Проинициализируем ListView в активити и присвоим ему адаптер.

ListView lessonListView = (ListView) findViewById(R.id.lessonList);
LessonListAdapter appListAdapter = new LessonListAdapter(this, lessonsList);
lessonListView.setAdapter(appListAdapter);

В папке res/menu/ создайте файл main.xml :

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    >
	<item
		android:id="@+id/menu_item_is_favorite"
		android:showAsAction="always"
		android:icon="@drawable/ic_is_favorite"
		android:title="@string/favorite"
	/>
	<item
		android:id="@+id/menu_item_no_favorite"
		android:showAsAction="always"
		android:icon="@drawable/ic_favorite"
		android:title="@string/favorite"
	/>
</menu>

Как видите, у нас два похожих пункта меню. Они отличаются только иконкой и id.

Layout-файл от Lesson-активити:

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

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5dp" />

</LinearLayout>

Создаем класс LessonActivity, наследника Activity.

package ru.javahelp.addtofavorite;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class LessonActivity extends Activity{

	private Lesson lesson;
	private int position = 0;
	private TextView textView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.lesson);
		
		if (getIntent() != null) {
			position = getIntent().getIntExtra("position", -1);
		}
		
		lesson = MainActivity.lessonsList.get(position);
		textView = (TextView) findViewById(R.id.textView);
		textView.setText(lesson.getText());
	}
	
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		MenuItem fave = menu.findItem(R.id.menu_item_is_favorite);
		MenuItem unfave = menu.findItem(R.id.menu_item_no_favorite);

		if (lesson != null) {
			fave.setVisible(lesson.isFavorite());
			unfave.setVisible(!lesson.isFavorite());
		} else {
			fave.setVisible(false);
			unfave.setVisible(false);
		}
		return true;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.lesson, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		case R.id.menu_item_no_favorite:
			setFavorite(true);
			return true;

		case R.id.menu_item_is_favorite:
			setFavorite(false);
			return true;

		default:
			return super.onOptionsItemSelected(item);
		}
	}
	
	void setFavorite(boolean isFavorite) {
		lesson.setFavorite(isFavorite);
		invalidateOptionsMenu();
	}
	
}

В onCreate мы достаем из Intent’а позицию урока. Далее получаем урок по позиции. При нажатии на пункт меню с ID menu_item_no_favorite мы скрываем его и делаем видимым пункт с ID menu_item_is_favorite  и наоборот. Вызывая метод invalidateOptionsMenu(), мы вызываем пересоздание меню с измененными параметрами. Таким образом мы показываем пользователю находится урок в избранном или нет.

scr1

Исходники примера: AddToFavorite.

 

Комментарии:

3 comments

  1. Waki Reply

    Неплохо было бы добавлять скриншоты

  2. Сергей Reply

    А как потом просмотреть список избранного?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *