com.twolinessoftware.smarterlist.view.MasterSmartListCategoryRecyclerViewAdapter.java Source code

Java tutorial

Introduction

Here is the source code for com.twolinessoftware.smarterlist.view.MasterSmartListCategoryRecyclerViewAdapter.java

Source

/*
 * Copyright (c) 2015. 2Lines Software,Inc
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

package com.twolinessoftware.smarterlist.view;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.squareup.otto.Bus;
import com.squareup.picasso.Picasso;
import com.twolinessoftware.smarterlist.Injector;
import com.twolinessoftware.smarterlist.R;
import com.twolinessoftware.smarterlist.event.OnNavigateToCategory;
import com.twolinessoftware.smarterlist.model.MasterSmartCategory;
import com.twolinessoftware.smarterlist.model.MasterSmartListItem;
import com.twolinessoftware.smarterlist.model.SmartListItem;
import com.twolinessoftware.smarterlist.model.dao.SmartListItemDAO;
import com.twolinessoftware.smarterlist.util.Ln;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import javax.inject.Inject;

import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created by John on 2015-03-26.
 */
public class MasterSmartListCategoryRecyclerViewAdapter extends RecyclerView.Adapter<GenericListViewHolder>
        implements AdapterLifecycleInterface {

    private final Context m_context;

    private final Observable<List<MasterSmartListItem>> m_queryObservable;

    private final long m_smartListId;

    public List<SmartListItem> m_smartListCache = new ArrayList<SmartListItem>();

    public List<MasterSmartCategory> m_entries = new ArrayList<MasterSmartCategory>();

    @Inject
    SmartListItemDAO m_smartListItemDao;

    @Inject
    Bus m_eventBus;

    private final Handler m_refreshHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            notifyDataSetChanged();
        }
    };

    public MasterSmartListCategoryRecyclerViewAdapter(Context context,
            Observable<List<MasterSmartListItem>> queryObservable, long smartListId) {
        this.m_context = context;
        this.m_queryObservable = queryObservable;
        this.m_smartListId = smartListId;

        Injector.inject(this);

    }

    private MasterSmartItemChangesSubscriber m_masterListChangesSubscriber;

    private class MasterSmartItemChangesSubscriber extends Subscriber<List<MasterSmartListItem>> {

        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {
            Ln.e("Error loading data: " + Log.getStackTraceString(e));
        }

        @Override
        public void onNext(List<MasterSmartListItem> smartListItemList) {

            List<MasterSmartCategory> items = mapCategories(smartListItemList);

            Ln.v("Updating list with " + items.size() + " items");

            synchronized (m_entries) {

                ArrayList<MasterSmartCategory> removed = new ArrayList<>(m_entries);
                removed.removeAll(items);

                Ln.v("Removing " + removed.size() + " items");

                // delete the removed items from the current list
                m_entries.removeAll(removed);

                // determine the new items by removing the existing items from the list
                items.removeAll(m_entries);

                Ln.v("Adding " + items.size() + " items");

                int position = m_entries.size();
                for (MasterSmartCategory item : items) {
                    m_entries.add(item);
                }
                notifyItemRangeInserted(position, items.size());

                notifyDataSetChanged();
            }

        }
    }

    private MasterListItemSubscriber m_smartListChangesSubscriber;

    private class MasterListItemSubscriber extends Subscriber<List<SmartListItem>> {

        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onNext(List<SmartListItem> smartListItems) {
            Ln.v("Updating cache:" + smartListItems.size());
            synchronized (m_smartListCache) {
                m_smartListCache = smartListItems;
            }
            m_refreshHandler.sendEmptyMessage(0);
        }
    }

    private void registerObservers() {

        if (m_masterListChangesSubscriber != null) {
            m_masterListChangesSubscriber.unsubscribe();
        }
        m_masterListChangesSubscriber = new MasterSmartItemChangesSubscriber();
        m_queryObservable.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())
                .subscribe(m_masterListChangesSubscriber);

        if (validateAgainstSmartList()) {

            if (m_smartListChangesSubscriber != null) {
                m_smartListChangesSubscriber.unsubscribe();
            }
            m_smartListChangesSubscriber = new MasterListItemSubscriber();

            m_smartListItemDao.monitorSmartList(m_smartListId).subscribeOn(Schedulers.newThread())
                    .subscribe(m_smartListChangesSubscriber);

        }

    }

    private boolean validateAgainstSmartList() {
        return m_smartListId != 0;
    }

    private String getCaptionText(long categoryId) {
        if (validateAgainstSmartList()) {
            StringBuilder sb = new StringBuilder();
            for (SmartListItem item : m_smartListCache) {
                if (item.getCategoryId() == categoryId && !item.isChecked()) {
                    if ((sb.length() + item.getName().length()) < 80) {
                        if (sb.length() > 0) {
                            sb.append(", ");
                        }
                        sb.append(item.getName());
                    } else {
                        sb.append("...");
                        break;
                    }
                }
            }

            return sb.toString();
        }
        return null;
    }

    @Override
    public void onPause() {
        m_masterListChangesSubscriber.unsubscribe();
        m_smartListChangesSubscriber.unsubscribe();
    }

    @Override
    public void onResume() {
        registerObservers();
    }

    @Override
    public int getItemViewType(int position) {
        return super.getItemViewType(position);
    }

    @Override
    public GenericListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_listview, parent, false);

        GenericListViewHolder vh = new GenericListViewHolder(v);

        v.setOnClickListener(v1 -> {
            MasterSmartCategory category = (MasterSmartCategory) v1.getTag();
            ViewCompat.setTransitionName(v1, "viewtransition_" + category.getId());

            m_eventBus.post(new OnNavigateToCategory(v1, category));
        });

        return vh;
    }

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

        MasterSmartCategory item = m_entries.get(position);

        holder.getView().setTag(item);
        holder.setText(item.getName());

        String caption = getCaptionText(item.getId());
        holder.setCaption(caption);
        holder.textMain.setTextColor(item.getColor());
        holder.colorSideBar.setBackgroundColor(item.getColor());

        // @todo add error image
        Picasso.with(m_context).load(item.getIconUrl()).into(holder.icon);

    }

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

    private List<MasterSmartCategory> mapCategories(List<MasterSmartListItem> items) {
        HashSet<MasterSmartCategory> categories = new HashSet<>();

        for (MasterSmartListItem item : items) {
            MasterSmartCategory category = new MasterSmartCategory(item.getCategoryId(), item.getCategoryName(),
                    item.getCategoryColor(), item.getCategoryIconUrl());
            categories.add(category);
        }

        return new ArrayList<>(categories);

    }

}