Domain Modeling Made Functional (DevTernity 2022)Scott Wlaschin
(video at https://fsharpforfunandprofit.com/ddd/)
Statically typed functional programming languages encourage a very different way of thinking about types. The type system is your friend, not an annoyance, and can be used in many ways that might not be familiar to OO programmers. Types can be used to represent the domain in a fine-grained, self documenting way. And in many cases, types can even be used to encode business rules so that you literally cannot create incorrect code. You can then use the static type checking almost as an instant unit test — making sure that your code is correct at compile time. In this talk, we'll look at some of the ways you can use types as part of a domain driven design process, with some simple real world examples in F#. No jargon, no maths, and no prior F# experience necessary.
運用してわかったLookerの本質的メリット : Data Engineering Study #8Masatoshi Abe
Data Engineering Study #8 でのLooker事例発表です。
https://forkwell.connpass.com/event/209803/
BIツールの運用コストは「データアーキテクチャの複雑さ」と「アウトプットの多様さ」の掛け合わせで決まると考えています。その2つをマネジメントしやすいBIツールとして、株式会社ヤプリのLooker事例をご紹介します。Lookerは「強くてニューゲーム」ができる素敵なツールだと思います。
This document provides an overview of how to build custom layout managers for RecyclerView. It discusses the key components like the LayoutManager, Adapter and techniques like fill to layout views in gaps. It then outlines 4 levels of implementation from making a basic layout manager work to more advanced features like predictive item animations and smooth scrolling. Resources for learning more about building custom RecyclerView layouts are also provided.
運用してわかったLookerの本質的メリット : Data Engineering Study #8Masatoshi Abe
Data Engineering Study #8 でのLooker事例発表です。
https://forkwell.connpass.com/event/209803/
BIツールの運用コストは「データアーキテクチャの複雑さ」と「アウトプットの多様さ」の掛け合わせで決まると考えています。その2つをマネジメントしやすいBIツールとして、株式会社ヤプリのLooker事例をご紹介します。Lookerは「強くてニューゲーム」ができる素敵なツールだと思います。
This document provides an overview of how to build custom layout managers for RecyclerView. It discusses the key components like the LayoutManager, Adapter and techniques like fill to layout views in gaps. It then outlines 4 levels of implementation from making a basic layout manager work to more advanced features like predictive item animations and smooth scrolling. Resources for learning more about building custom RecyclerView layouts are also provided.
This presentation is about RecyclerView
and special features which can make work with it even better: Adapter, LayoutManager, ItemAnimator, ItemDecoration etc.
Presentation by Oleksandr Kravchenko (Software Engineer, GlobalLogic, Lviv), delivered at Mobile TechTalk Lviv on April 28, 2015.
More details - http://globallogic.com.ua/mobile-techtalk-lviv-2015-report
This document discusses techniques for optimizing RecyclerView performance in Android applications. It begins by introducing RecyclerView and its architecture using ViewHolders. It then discusses best practices such as performing expensive operations off the main thread, limiting unnecessary layout passes, and using view holder patterns. The document also covers optimizations like prefetching data to improve scrolling performance and avoiding rebinding views unnecessarily. Overall, the key message is that recycling views and keeping the UI thread lightweight are important for smooth RecyclerView experiences.
Chia sẻ của anh Lê Văn Giáp: Android Tech Leader- VCCorp, Tech Advisor GDG Hanoi, Founder/Admin VietAndroid.com, cựu CEO của ViMarket - Kho ứng dụng thuần Việt đầu tiên của VN.
The document provides an overview of RecyclerView in Android, including:
1. RecyclerView components like LayoutManager, Adapter, ItemDecoration, and ItemAnimator and examples of how to set them up.
2. How to create ViewHolders and Adapters to display data in RecyclerView.
3. Techniques for handling click listeners and displaying multiple view types.
4. Examples of using item decorations and animators.
5. Recommended resources for further learning about RecyclerView.
Bonnes pratiques et méthodes pour le développement sur Android ; Collectées ici et là à travers différentes conférences, lectures et pratiques du développement android.
This document discusses the RecyclerView component in Android and the concept of ExtraLayoutSpace. It is authored by Yuki Mima, an Android app engineer. ExtraLayoutSpace refers to the amount of extra space that the LayoutManager can use to pre-load views for smooth scrolling. The document recommends overriding the LinearLayoutManager's getExtraLayoutSpace method to implement custom pre-caching logic, though it notes this may have performance costs versus user experience benefits.
Este documento descreve como criar um aplicativo simples de vendas com Android. O objetivo é criar uma lista de produtos usando RecyclerView e exibir detalhes de um produto em outra tela. Ele cobre tópicos como criar classes de modelo, popular uma lista, construir um Adapter para vincular os dados, baixar imagens com Picasso, passar parâmetros entre activities e personalizar a ActionBar.
Android Training (AdapterView & Adapter)Khaled Anaqwa
The AdapterView is a ViewGroup that displays data through an Adapter. Common subclasses are ListView, Spinner, and Gallery. The Adapter provides the data and Views for each item. AdapterView is responsible for displaying the items and handling user selection. ListActivity simplifies displaying a list bound to an Adapter. The Adapter populates the list and notifies the AdapterView of data changes.
The document discusses various topics related to Android development including:
1. Lists several popular running and exercise tracking apps for Android.
2. Discusses techniques for customizing the Android action bar and removing the title bar from an activity's view.
3. Provides examples of creating gradient colors for use in activities and the action bar.
This document discusses fragments in Android. It covers defining fragments in XML layout files using the <fragment> tag, communicating between fragments and activities, and how fragments were implemented before Android 3.0 using ActivityGroup and LocalActivityManager which are now deprecated. The document also discusses how fragments are used to modularize parts of an app's UI and how they are meant to be reusable components.
The document discusses an Android layout cookbook seminar that covers improving functions, the layout hierarchy, tabs versus buttons, menus, action bars, asynchronous tasks, and progress. The seminar was created by @vvakame and includes topics like the main function, sub functions, QR codes, long taps, and a coffee break.
The document discusses Android layout concepts including margin, padding, LinearLayout, ImageView, GridView, and ListView. It explains that padding is the space between the content of a view and its border, while margin is the space outside the border of a view. It also distinguishes between base/main color and point color.
44. アイテム用のViewのOffsetを指定
final int offset =
(int) (8 * getResources().getDisplayMetrics().density);
final RecyclerView.ItemDecoration itemDecoration =
new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(Rect outRect,
View view,
RecyclerView parent,
RecyclerView.State state) {
outRect.set(offset, offset, offset, offset);
}
};
recyclerView.addItemDecoration(itemDecoration);
46. アイテム用のViewのOffsetを指定
final RecyclerView.ItemDecoration itemDecoration =
new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(Rect outRect,
View view,
RecyclerView parent,
RecyclerView.State state) {
int position = ((RecyclerView.LayoutParams)
view.getLayoutParams()).getViewLayoutPosition();
if (position == 0) {
outRect.set(offset, offset, offset, offset);
} else {
outRect.set(offset, 0, offset, offset);
}
}
};
recyclerView.addItemDecoration(itemDecoration);
48. private static class DividerDecoration extends
RecyclerView.ItemDecoration {
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final int dividerHeight;
public DividerDecoration(Resources res) {
paint.setColor(Color.GRAY);
dividerHeight
= (int) (4 * res.getDisplayMetrics().density);
}
@Override
public void getItemOffsets(Rect outRect,
View view,
RecyclerView parent,
RecyclerView.State state) {
int position = ((RecyclerView.LayoutParams)
view.getLayoutParams()).getViewLayoutPosition();
Dividerを描画
49. dividerHeight
= (int) (4 * res.getDisplayMetrics().density);
}
@Override
public void getItemOffsets(Rect outRect,
View view,
RecyclerView parent,
RecyclerView.State state) {
int position = ((RecyclerView.LayoutParams)
view.getLayoutParams()).getViewLayoutPosition();
// 位置が2番目以降なら上部にdividerを描画したいので、
// divider分だけ上をあける
int top = position == 0 ? 0 : dividerHeight;
outRect.set(0, top, 0, 0);
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent,
RecyclerView.State state) {
super.onDrawOver(c, parent, state);
// アイテムのビューより上に描画される
}
Dividerを描画
50. @Override
public void onDraw(Canvas c, RecyclerView parent,
RecyclerView.State state) {
super.onDraw(c, parent, state);
// アイテムのビューより下に描画される
final RecyclerView.LayoutManager manager =
parent.getLayoutManager();
final int left = parent.getPaddingLeft();
final int right = parent.getWidth()
- parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 1; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params =
(RecyclerView.LayoutParams) child.getLayoutParams()
if (params.getViewLayoutPosition() == 0) {
continue;
}
// ViewCompat.getTranslationY()を入れないと
Dividerを描画
51.
final RecyclerView.LayoutManager manager =
parent.getLayoutManager();
final int left = parent.getPaddingLeft();
final int right = parent.getWidth()
- parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 1; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params =
(RecyclerView.LayoutParams) child.getLayoutParams()
if (params.getViewLayoutPosition() == 0) {
continue;
}
// ViewCompat.getTranslationY()を入れないと
// 追加・削除のアニメーション時の位置が変になる
final int top = manager.getDecoratedTop(child)
- params.topMargin
+ Math.round(ViewCompat.getTranslationY(child))
final int bottom = top + dividerHeight;
c.drawRect(left, top, right, bottom, paint);
}
}
}
Dividerを描画
56. // selectableItemBackgroundに指定されている
// リソースIDの値を取得しておく
TypedValue val = new TypedValue();
if (getTheme() != null) {
getTheme().resolveAttribute(
android.R.attr.selectableItemBackground,
val, true);
}
final int backgroundResId = val.resourceId;
final SimpleAdapter adapter = new SimpleAdapter(this, data) {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
final ViewHolder viewHolder
= super.onCreateViewHolder(parent, viewType);
viewHolder.itemView.setBackgroundResource(backgroundRes
viewHolder.itemView.setOnClickListener(
OnItemClick
57. final SimpleAdapter adapter = new SimpleAdapter(this, data) {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
final ViewHolder viewHolder
= super.onCreateViewHolder(parent, viewType);
viewHolder.itemView.setBackgroundResource(backgroundRes
viewHolder.itemView.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = viewHolder
.getAdapterPosition();
Toast.makeText(v.getContext(),
"Position = " + position,
Toast.LENGTH_SHORT).show();
}
});
return viewHolder;
}
};
recyclerView.setAdapter(adapter);
OnItemClick
61. notify**
• notifyItemRangeChanged(int positionStart, int itemCount) :
positionStartからitemCount個のアイテムが変更された
• notifyItemRangeInserted(int positionStart, int itemCount) :
positionStartにitemCount個のアイテムが追加された
• notifyItemRangeRemoved(int positionStart, int
itemCount) : positionStartからitemCount個のアイテムが削
除された
• notifyDataSetChanged() : データセットが変更された
62. public abstract class RecyclerArrayAdapter<T, VH extends
RecyclerView.ViewHolder>
extends RecyclerView.Adapter<VH> {
private final Object lock = new Object();
private final Context context;
private final List<T> objects;
public RecyclerArrayAdapter(Context context) {
this(context, new ArrayList<T>());
}
public RecyclerArrayAdapter(Context context, List<T> objects
this.context = context;
this.objects = objects;
}
public void add(@NonNull T object) {
final int position = objects.size();
ArrayAdapter的なRecyclerView用Adapter
63.
public RecyclerArrayAdapter(Context context, List<T> objects
this.context = context;
this.objects = objects;
}
public void add(@NonNull T object) {
final int position = objects.size();
synchronized (lock) {
objects.add(object);
}
notifyItemInserted(position);
}
public void addAll(@NonNull Collection<? extends T> collecti
final int positionStart = objects.size();
final int itemCount = collection.size();
synchronized (lock) {
objects.addAll(collection);
}
notifyItemRangeInserted(positionStart, itemCount);
}
public void insert(@NonNull T object, int index) {
synchronized (lock) {
ArrayAdapter的なRecyclerView用Adapter
64. objects.addAll(collection);
}
notifyItemRangeInserted(positionStart, itemCount);
}
public void insert(@NonNull T object, int index) {
synchronized (lock) {
objects.add(index, object);
}
notifyItemInserted(index);
}
public void remove(@NonNull T object) {
int position = getPosition(object);
synchronized (lock) {
objects.remove(object);
}
notifyItemRemoved(position);
}
public void clear() {
final int itemCount = objects.size();
synchronized (lock) {
objects.clear();
}
notifyItemRangeRemoved(0, itemCount);
ArrayAdapter的なRecyclerView用Adapter
66. ItemTouchHelper
• RecyclerViewに swipe to dismiss と drag & drop による並
び替え機能を追加するためにユーティリティクラス
ItemTouchHelper.Callback callback = …;
ItemTouchHelper itemTouchHelper =
new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyclerView);
67. swipe to dismiss
• ItemTouchHelper.Callbackのコンストラクタの第2引数で
スワイプ方向を指定
• スワイプされたらonSwiped()が呼ばれる
68. swipe to dismiss
int swipeDirs = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
ItemTouchHelper.Callback callback =
new ItemTouchHelper.SimpleCallback(0, swipeDirs) {
…
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder,
int direction) {
int position = viewHolder.getAdapterPosition();
adapter.remove(adapter.getItem(position));
}
};
69. drag and drop
• ItemTouchHelper.Callbackのコンストラクタの第1引数で
ドラッグ方向を指定
• ドロップされたらonMove()が呼ばれる
• ドラッグが開始できるようになったタイミングで
onSelectedChanged()が呼ばれる
• ドラッグを終了するときにclearView()が呼ばれる
70. int dragDirs = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
ItemTouchHelper.Callback callback = new
ItemTouchHelper.SimpleCallback(dragDirs, 0) {
@Override
public boolean onMove(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder,
RecyclerView.ViewHolder target) {
int from = viewHolder.getAdapterPosition();
int to = target.getAdapterPosition();
adapter.move(from, to);
return true;
}
…
};
drag and drop
71. int dragDirs = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
ItemTouchHelper.Callback callback = new
ItemTouchHelper.SimpleCallback(dragDirs, 0) {
@Override
public boolean onMove(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder,
RecyclerView.ViewHolder target) {
int from = viewHolder.getAdapterPosition();
int to = target.getAdapterPosition();
adapter.move(from, to);
return true;
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHo
int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
viewHolder.itemView.setBackgroundColor(Color.LTGRAY)
}
drag and drop
72. int to = target.getAdapterPosition();
adapter.move(from, to);
return true;
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHo
int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
viewHolder.itemView.setBackgroundColor(Color.LTGRAY)
}
super.onSelectedChanged(viewHolder, actionState);
}
@Override
public void clearView(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
viewHolder.itemView.setBackgroundColor(Color.TRANSPARENT
}
…
}
};
drag and drop
76. public class SimpleListLayoutManager extends
RecyclerView.LayoutManager {
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams()
return new RecyclerView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler,
RecyclerView.State state) {
// 現在表示されている一番上のビューの位置を保持しておく
final View lastTopView = getChildCount() > 0 ?
getChildAt(0) : null;
final int lastTop = lastTopView != null ?
lastTopView.getTop() : getPaddingTop();
final int firstPosition = lastTopView != null ?
getPosition(lastTopView) : 0;
独自のLayoutManager
77. final int lastTop = lastTopView != null ?
lastTopView.getTop() : getPaddingTop();
final int firstPosition = lastTopView != null ?
getPosition(lastTopView) : 0;
// 現在のビューをスクラップにする
detachAndScrapAttachedViews(recycler);
int top = lastTop;
int bottom;
final int parentLeft = getPaddingLeft();
final int parentRight = getWidth() - getPaddingRight();
final int parentBottom = getHeight() - getPaddingBottom();
final int count = state.getItemCount();
for (int i = 0; firstPosition + i < count &&
top < parentBottom; i++, top = bottom) {
View v = recycler.getViewForPosition(firstPosition + i)
addView(v, i);
measureChildWithMargins(v, 0, 0);
bottom = top + getDecoratedMeasuredHeight(v);
layoutDecorated(v, parentLeft, top, parentRight, bottom
}
}
}
独自のLayoutManager