Ignat Makarenko

Android and Java Development

List++

List++ is a Personal Information Management System for Android. It can help you to manage everyday tasks, like creating To-Do-Lists or manage your personal inventory.
The two-list interaction approach makes it unique. It has not one main list, like almost all default Personal Management Systems like a shopping list. It hast two, one on the left (categories) and one on the right (items). A category is simply a folder or a box. An item could be everything. It could be an apple, a car, a reminder-note or any other object. You can click on the item-object and make notes or add a picture.
The benefit of a dual-list-app is the possibility to create and nest categories.  For example, creating a purchase-list: You can now create categories like food and clothes. You can further create sub-categories like vegetables and fruits and put them into the food-category. Now, if you want to buy some food in one store and some other food in the other store, then just create store-categories and move the food-categories (or items) through drag-and-drop in there. By swiping you can rename or remove them.
Implementation
List++ consists of two main lists (list = android recyclerviews). On the right side a list with category-items and on the left a list with item-items. Every item consist of a list as well. An Item is technically a list in a list (nested recyclerviews). This enables the posibility of swiping items, to get additional options (which are not visible in the beginning) like removing or renaming them. Every item has a long-click-listener. A longclick is triggering a dragevent. Every item has a draglistener as well, so it is possible to take an item and drag it anywhere. This enables the possibility of interaction between the category- and the item-list. To enable this interaction through drag and drop though, it was necessary to create a custom drag-shadow-builder, which can transfer informations between different recyclerviews.
Every interaction has a function. A long-click-event leads to a drag-start. A swipe enables additional options. A short click on a category navigates into it's subcategories. A short click opens the item's fragment. An item's fragment shows the item (representation). The item-fragment has other fragments inside of it, such as comment-creation-fragment and add-picture-fragment etc.

Small Codesnippet

   private int layout = R.layout.item_navigation;
   private DataManager dataManager;
   private LinearLayoutManager layoutManager;
   private List dataList;
   private Category currentCategory;
   private RecyclerView selectedRecyclerView;
   private boolean showSubs;

   NavigationAdapater(DataManager dataManager) {
       this.selectedRecyclerView = dataManager.getMainContext().findViewById(R.id.navigation);
       this.dataManager = dataManager;
       this.showSubs = false;
       this.layoutManager = new LinearLayoutManager(dataManager.getMainContext(), LinearLayoutManager.HORIZONTAL, false);
       selectedRecyclerView.setLayoutManager(this.layoutManager);
       selectedRecyclerView.setAdapter(this);
   }

   void setDataList(Element element, boolean showSubs) {
       if (element instanceof Category){
           this.currentCategory = (Category) element;
           this.dataList = Static.getCategoryBreadcrumb(currentCategory);
       }
       if (element instanceof Item){
           this.currentCategory = Static.getCategoryOfItem(dataManager, (Item) element);
           this.dataList = Static.getCategoryBreadcrumb(this.currentCategory);
       }
       this.showSubs = showSubs;
       layoutManager.removeAllViews();
       notifyDataSetChanged();
       //dataManager.updateGUI();
       dataManager.getDrawView().invalidate();
   }

    static class ViewHolder extends RecyclerView.ViewHolder {
       RecyclerView outerRV;
       ViewHolder(View v) {
           super(v);
           this.outerRV = v.findViewById(R.id.itemOuterRV);
       }
   }

   public RecyclerView getSelectedRecyclerView() {
       return selectedRecyclerView;
   }

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

   @NonNull
   @Override
   public NavigationAdapater.ViewHolder onCreateViewHolder(@NonNull ViewGroup recyclerView, int i) {
       ConstraintLayout v = (ConstraintLayout) LayoutInflater.from(recyclerView.getContext()).inflate(layout, recyclerView, false);
       return new ViewHolder(v);
   }

   @Override
   public void onBindViewHolder(@NonNull final NavigationAdapater.ViewHolder viewHolder, int i) {
       viewHolder.setIsRecyclable(false);
       int position = viewHolder.getAdapterPosition();
       if (position < dataList.size()) {
           new NavigationInnerAdapter(dataManager, viewHolder.outerRV, (Category) dataList.get(position), this);
       } else {
           if (showSubs) {
               new NavigationInnerAdapter(dataManager, viewHolder.outerRV, currentCategory.getSubcategory(), this);
           }
       }
   }

   private boolean isShowSubs() {
       return showSubs;
   }

   @Override
   public int getItemCount() {
       //wenn noch nicht alles initialisiert ist
       if (currentCategory == null){
           return 0;
       }
       int size;
       if (!currentCategory.getSubcategory().isEmpty() && showSubs) {
           size = dataList.size() + 1;
       } else {
           size = dataList.size();
       }
       return size;
   }

   public Category getCurrentCategory() {
       return this.currentCategory;
   }

private static class NavigationInnerAdapter extends RecyclerView.Adapter<navigationinneradapter.viewholder> implements View.OnClickListener {</navigationinneradapter.viewholder>
       private DataManager dataManager;
       private Category category;
       private int size;
       private ArrayList<category> subcategories;</category>
       private NavigationAdapater navigationAdapater;


       NavigationInnerAdapter(DataManager dataManager, RecyclerView recyclerView, Category category, NavigationAdapater navigationAdapater) {
           this.dataManager = dataManager;
           this.category = category;
           this.navigationAdapater = navigationAdapater;
           LinearLayoutManager layoutManagerHorizontal = new LinearLayoutManager(dataManager.getMainContext(), LinearLayoutManager.VERTICAL, false);
           recyclerView.setLayoutManager(layoutManagerHorizontal);
           recyclerView.setAdapter(this);
           size = 1;
       }

       NavigationInnerAdapter(DataManager dataManager, RecyclerView recyclerView, ArrayList<category> subcategory, NavigationAdapater navigationAdapater) {</category>
           this.dataManager = dataManager;
           this.subcategories = subcategory;
           this.navigationAdapater = navigationAdapater;
           LinearLayoutManager layoutManagerHorizontal = new LinearLayoutManager(dataManager.getMainContext(), LinearLayoutManager.VERTICAL, false);
           recyclerView.setLayoutManager(layoutManagerHorizontal);
           recyclerView.setAdapter(this);
           size = subcategories.size();
       }

       static class ViewHolder extends RecyclerView.ViewHolder {
           TextView text;
           ViewHolder(View view) {
               super(view);
               this.text = view.findViewById(R.id.text);
           }
       }

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

       @NonNull
       @Override
       public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) {
           View v;
           if (category == dataManager.getMain()) {
               v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_category_navigation1, viewGroup, false);
           } else {
               v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_category_navigation, viewGroup, false);
           }
           return new ViewHolder(v);
       }

       @Override
       public void onBindViewHolder(@NonNull ViewHolder viewHolder, int p) {
           viewHolder.setIsRecyclable(false);
           int position = viewHolder.getAdapterPosition();
           if (!isSubs()) {
               if (category != dataManager.getMain()) {
                   viewHolder.text.setText(category.getName());
               }
               viewHolder.itemView.setTag(category);
               viewHolder.itemView.setOnClickListener(this);
               int childCount = navigationAdapater.getSelectedRecyclerView().getChildCount();
               if (childCount == navigationAdapater.getItemCount()) {
                   viewHolder.text.setTextSize(16);
                   viewHolder.text.setTypeface(null, Typeface.BOLD);
               } else {
                   if (category == dataManager.getMain()) {
                       viewHolder.text.setText(viewHolder.text.getText() + "            >  ");
                   } else {
                       viewHolder.text.setText(viewHolder.text.getText() + "   >  ");
                   }
               }
           }
           if (isSubs()) {
               viewHolder.text.setText(subcategories.get(position).getName());
               viewHolder.itemView.setTag(subcategories.get(position));
               viewHolder.itemView.setOnClickListener(this);
               int childAtIndex = navigationAdapater.getItemCount()-2;
               ConstraintLayout constraintLayout = (ConstraintLayout) navigationAdapater.getSelectedRecyclerView().getChildAt(childAtIndex);
               RecyclerView recyclerView = (RecyclerView) constraintLayout.getChildAt(0);
               ConstraintLayout constraintLayout1 = (ConstraintLayout) recyclerView.getChildAt(0);
               TextView textView = (TextView) constraintLayout1.getChildAt(0);
               textView.setTextSize(16);
               textView.setTypeface(null, Typeface.BOLD);
           }
       }

       private boolean isSubs() {
           return category == null;
       }

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

       @Override
       public void onClick(View view) {
           Category category = (Category) view.getTag();
           if (isSubs()) {
               dataManager.getItemSliderFragment().handleOnBackPressed();
               dataManager.getNavigationAdapater().setDataList(category,false);
               List<category> categories = category.getCategories(Category.DIRECT_SUBCATEGORIES_WITHOUT_PARENT);</category>
               Static.sort(categories);
               dataManager.getVerticalAdapterLeft().setDataList(categories, Category.class);
               dataManager.getDrawView().invalidate();
               return;
           }

           dataManager.getNavigationAdapater().setDataList(category,navigationAdapater.isShowSubs());
           dataManager.getVerticalAdapterRight().setDataList(category.getAllItems(), Item.class, true);
           List<category> categories = category.getCategories(Category.DIRECT_SUBCATEGORIES_WITHOUT_PARENT);</category>
           Static.sort(categories);
           if (dataManager.isFragmentCreated("ItemSliderFragment")) {
               dataManager.getItemSliderFragment().setCategory(category);
           }
           dataManager.getVerticalAdapterLeft().setDataList(categories, Category.class);
           dataManager.getDrawView().invalidate();
       }
   }
}

Pkr++

Implementation
Pkr++ is a poker tool using techniques from Big Data analysis. This app is designed for Anroid-Tablets. It analysis a given database through RegEx and visualize the outcome. In this example the question was, which starterhands in poker are profitable from which position and what are the appropriate decisions based on the positions of the players (Nash equilibrium calculations). On the bottom are check-boxes for position input. The four lists (Recyclerviews) adept to the input (activated check-boxes).

Small Codesnippet

package com.example.pkrplusplus.poker;

import android.graphics.Typeface;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.example.pkrplusplus.Main;
import com.example.pkrplusplus.R;
import java.util.ArrayList;
import java.util.List;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.Guideline;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;


public class PokerAdapter extends RecyclerView.Adapter<PokerAdapter.ViewHolder> {
   private int layout = R.layout.poker_outer_rv;
   private Main main;
   private LinearLayoutManager layoutManager;
   private List dataList;
   private RecyclerView recyclerView;
   PokerFragment pokerFragment;


   PokerAdapter(Main main, ArrayList<String> dataList, RecyclerView recyclerView, PokerFragment pokerFragment) {
       this.pokerFragment = pokerFragment;
       this.dataList = dataList;
       this.recyclerView = recyclerView;
       this.main = main;
       this.layoutManager = new LinearLayoutManager(main, LinearLayoutManager.VERTICAL, false);
       recyclerView.setLayoutManager(this.layoutManager);
       recyclerView.setAdapter(this);
   }

   public ArrayList<ConstraintLayout> getAllHandViews() {
       ArrayList<ConstraintLayout> allViews = new ArrayList<>();
       for (int i = 0; i < recyclerView.getChildCount(); i++) {
           ConstraintLayout layout = (ConstraintLayout) recyclerView.getChildAt(i);
           RecyclerView recyclerViewSub = (RecyclerView) layout.getChildAt(0);
           for (int j = 0; j < recyclerViewSub.getChildCount(); j++) {
               ConstraintLayout subayout = (ConstraintLayout) recyclerViewSub.getChildAt(j);
               allViews.add(subayout);
           }
       }
       return allViews;
   }

   static class ViewHolder extends RecyclerView.ViewHolder {
       RecyclerView outerRV;

       ViewHolder(View v) {
           super(v);
           this.outerRV = v.findViewById(R.id.pokerOuterRv);
       }
   }


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


   @Override
   public PokerAdapter.ViewHolder onCreateViewHolder(ViewGroup recyclerView, int i) {
       ConstraintLayout v = (ConstraintLayout) LayoutInflater.from(recyclerView.getContext()).inflate(layout, recyclerView, false);
       return new ViewHolder(v);
   }


   @Override
   public void onBindViewHolder(final PokerAdapter.ViewHolder viewHolder, int i) {
       viewHolder.setIsRecyclable(false);
       int position = viewHolder.getAdapterPosition();
       ArrayList list = (ArrayList) dataList.get(position);
       new PokerInnerAdapter(main, viewHolder.outerRV, list);
   }


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


   private class PokerInnerAdapter extends RecyclerView.Adapter<PokerInnerAdapter.ViewHolder> implements View.OnClickListener {
       private ArrayList list;

       PokerInnerAdapter(Main main, RecyclerView recyclerView, ArrayList list) {
           this.list = list;
           LinearLayoutManager layoutManagerHorizontal = new LinearLayoutManager(main.getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);
           recyclerView.setLayoutManager(layoutManagerHorizontal);
           recyclerView.setAdapter(this);
       }

       @Override
       public void onClick(View view) {
           if (view.isActivated()) {
               view.setBackgroundResource(R.color.colorGray);
           } else {
               view.setBackgroundResource(R.color.colorMainLayout);
           }
           String string = "";
           view.setActivated(!view.isActivated());
           RecyclerView recyclerView = (RecyclerView) view.getParent().getParent().getParent();
           for (int i = 0; i < recyclerView.getChildCount(); i++) {
               ConstraintLayout layout = (ConstraintLayout) recyclerView.getChildAt(i);
               RecyclerView recyclerViewSub = (RecyclerView) layout.getChildAt(0);
               for (int j = 0; j < recyclerViewSub.getChildCount(); j++) {
                   ConstraintLayout subayout = (ConstraintLayout) recyclerViewSub.getChildAt(j);
                   if (subayout.isActivated()) {
                       string += "pokerHandList.add(new PokerHand(\"" + subayout.getTag() + "\",1));" + "\n";
                   }
               }
           }
       }

       public void largeLog(String tag, String content) {
           if (content.length() > 4000) {
               Log.d(tag, content.substring(0, 4000));
               largeLog(tag, content.substring(4000));
           } else {
               Log.d(tag, content);
           }
       }

       class ViewHolder extends RecyclerView.ViewHolder {
           TextView text;
           ConstraintLayout constraintLayout;
           ConstraintLayout raiseLayout;
           ConstraintLayout callLayout;
           ConstraintLayout foldLayout;
           Guideline firstGuideline;
           Guideline secondGuideline;
           View handView;

           ViewHolder(View view) {
               super(view);
               this.constraintLayout = (ConstraintLayout) view;
               this.text = view.findViewById(R.id.pokerInnerText);
               this.raiseLayout = view.findViewById(R.id.pokerRaise);
               this.callLayout = view.findViewById(R.id.pokerCall);
               this.firstGuideline = view.findViewById(R.id.guidelineFirst);
               this.secondGuideline = view.findViewById(R.id.guidelineSecond);
               this.handView = view.findViewById(R.id.pokerInnerLayout);
           }
       }

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


       @Override
       public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {
           View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.poker_inner_layout, viewGroup, false);

           v.setOnClickListener(this);
           return new ViewHolder(v);
       }

       @Override
       public void onBindViewHolder(ViewHolder viewHolder, int p) {
           viewHolder.setIsRecyclable(false);
           viewHolder.text.setText("" + list.get(viewHolder.getAdapterPosition()));
           String string = (String) list.get(viewHolder.getAdapterPosition());
           if (string.length() == 2) {
               viewHolder.text.setTypeface(Typeface.DEFAULT_BOLD);
               viewHolder.text.setTextSize(14);
           }
           viewHolder.text.setTag(list.get(viewHolder.getAdapterPosition()));
           viewHolder.constraintLayout.setTag(list.get(viewHolder.getAdapterPosition()));

       }
       @Override
       public int getItemCount() {
           return 13;
       }
   }
}

Me

Hello, my name is Ignat Makarenko. I am a student at Julius-Maximilians-University, Wuerzburg. My passion is creating applications and solving specific problems with Java and Android. In the following section I want to present some of my skillset beyond my projects presented above.

Extract of university lectures from Human-Computer-Interaction

  • Softwaretechnik
  • Einführung  MCI
  • Grundlagen Algorithmen und Datenstrukturen
  • Grundlagen Psychologische Ergonomie
  • Java Programmierpraktikum
  • Spezielle Gebiete der Psychologie
  • Softwarepraktikum Schnittstellenentwurf
  • Softwarequalität
  • Usability und Softwareergnonomie
  • Forschungsmethoden
  • Interaktive Computergraphik
  • Methoden Benutzerzentrierter Gestaltung
  • Instruktionspsychologie
  • Aktuelle Trends der Mensch-Computer-Systeme
  • Medieninformatik 1
  • MCS-Projekt Informatik

Contact

I am looking forward to hearing from you!