私の具体的な質問は、次のような効果をどのように実現できるかです。 http://youtu.be/EJm7subFbQI
バウンス効果は重要ではありませんが、ヘッダーに「スティッキー」効果が必要です。どこから始めますか? API 8以上で実装できるものが必要です。
ありがとう。
この問題には既にいくつかの解決策があります。説明しているのはセクションヘッダーであり、Androidではstickyセクションヘッダーと呼ばれるようになりました。
編集:完全に動作する例のコードを追加するための空き時間がありました。それに応じて回答を編集しました。
サードパーティのコードを使用したくない(または、Xamarinなどで直接使用できない)場合、これは手作業でかなり簡単に実行できます。アイデアは、ヘッダーに別のListViewを使用することです。このリストビューには、ヘッダーアイテムのみが含まれます。ユーザーはスクロールできません(setEnabled(false))が、メインリストのスクロールに基づくコードからスクロールされます。したがって、2つのリスト-headerListviewとmainListview、および2つの対応するアダプターheaderAdapterとmainAdapterがあります。 headerAdapterはセクションビューのみを返しますが、mainAdapterは2つのビュータイプ(セクションとアイテム)をサポートします。メインリスト内の位置を取得し、セクションリスト内の対応する位置を返すメソッドが必要になります。
主な活動
public class MainActivity extends AppCompatActivity {
public static final int TYPE_SECTION = 0;
public static final int TYPE_ITEM = 1;
ListView mainListView;
ListView headerListView;
MainAdapter mainAdapter;
HeaderAdapter headerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainListView = (ListView)findViewById(R.id.list);
headerListView = (ListView)findViewById(R.id.header);
mainAdapter = new MainAdapter();
headerAdapter = new HeaderAdapter();
headerListView.setEnabled(false);
headerListView.setAdapter(headerAdapter);
mainListView.setAdapter(mainAdapter);
mainListView.setOnScrollListener(new AbsListView.OnScrollListener(){
@Override
public void onScrollStateChanged(AbsListView view, int scrollState){
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// this should return an index in the headers list, based one the index in the main list. The logic for this is highly dependent on your data.
int pos = mainAdapter.getSectionIndexForPosition(firstVisibleItem);
// this makes sure our headerListview shows the proper section (the one on the top of the mainListview)
headerListView.setSelection(pos);
// this makes sure that headerListview is scrolled exactly the same amount as the mainListview
if(mainAdapter.getItemViewType(firstVisibleItem + 1) == TYPE_SECTION){
headerListView.setSelectionFromTop(pos, mainListView.getChildAt(0).getTop());
}
}
});
}
public class MainAdapter extends BaseAdapter{
int count = 30;
@Override
public int getItemViewType(int position){
if((float)position / 10 == (int)((float)position/10)){
return TYPE_SECTION;
}else{
return TYPE_ITEM;
}
}
@Override
public int getViewTypeCount(){ return 2; }
@Override
public int getCount() { return count - 1; }
@Override
public Object getItem(int position) { return null; }
@Override
public long getItemId(int position) { return position; }
public int getSectionIndexForPosition(int position){ return position / 10; }
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = getLayoutInflater().inflate(R.layout.item, parent, false);
position++;
if(getItemViewType(position) == TYPE_SECTION){
((TextView)v.findViewById(R.id.text)).setText("SECTION "+position);
}else{
((TextView)v.findViewById(R.id.text)).setText("Item "+position);
}
return v;
}
}
public class HeaderAdapter extends BaseAdapter{
int count = 5;
@Override
public int getCount() { return count; }
@Override
public Object getItem(int position) { return null; }
@Override
public long getItemId(int position) { return position; }
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = getLayoutInflater().inflate(R.layout.item, parent, false);
((TextView)v.findViewById(R.id.text)).setText("SECTION "+position*10);
return v;
}
}
}
ここで注意すべき点がいくつかあります。メインビューリストの最初のセクションを表示したくないのは、重複するためです(ヘッダーに既に表示されています)。それを回避するには、mainAdapter.getCount()で:
return actualCount - 1;
getView()メソッドの最初の行が
position++;
これにより、メインリストは最初のセルを除くすべてのセルをレンダリングします。
もう1つは、headerListviewの高さがリストアイテムの高さと一致することを確認することです。この例では、高さが固定されていますが、アイテムの高さがdpの正確な値に設定されていない場合、注意が必要です。これに対処する方法については、この回答を参照してください: https://stackoverflow.com/a/41577017/291688
メインレイアウト
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/activity_main"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:paddingBottom="@dimen/activity_vertical_margin"
Android:paddingLeft="@dimen/activity_horizontal_margin"
Android:paddingRight="@dimen/activity_horizontal_margin"
Android:paddingTop="@dimen/activity_vertical_margin">
<ListView
Android:id="@+id/header"
Android:layout_width="match_parent"
Android:layout_height="48dp"/>
<ListView
Android:id="@+id/list"
Android:layout_below="@+id/header"
Android:layout_width="match_parent"
Android:layout_height="match_parent"/>
</RelativeLayout>
アイテム/ヘッダーのレイアウト
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical" Android:layout_width="match_parent"
Android:layout_height="48dp">
<TextView
Android:id="@+id/text"
Android:gravity="center_vertical"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
/>
</LinearLayout>
これをapp.gradleファイルに追加します
compile 'se.emilsjolander:StickyScrollViewItems:1.1.0'
次に、レイアウトを追加しましたAndroid:tag ="sticky"
LinearLayoutではなくtextviewやedittextのような特定のビューに対しては、次のようになります。また、データバインディングも使用しますが、無視してください。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android">
<data>
<variable
name="temp"
type="com.lendingkart.prakhar.lendingkartdemo.databindingmodel.BusinessDetailFragmentModel" />
<variable
name="presenter"
type="com.lendingkart.prakhar.lendingkartdemo.presenters.BusinessDetailsPresenter" />
</data>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<com.lendingkart.prakhar.lendingkartdemo.customview.StickyScrollView
Android:id="@+id/sticky_scroll"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<!-- scroll view child goes here -->
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<Android.support.v7.widget.CardView xmlns:card_view="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_gravity="center"
card_view:cardCornerRadius="5dp"
card_view:cardUseCompatPadding="true">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<TextView
style="@style/group_view_text"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="@drawable/businessdetailtitletextviewbackground"
Android:padding="@dimen/activity_horizontal_margin"
Android:tag="sticky"
Android:text="@string/business_contact_detail" />
<Android.support.design.widget.TextInputLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_margin="7dp">
<Android.support.design.widget.TextInputEditText
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:hint="@string/comapnyLabel"
Android:textSize="16sp" />
</Android.support.design.widget.TextInputLayout>
<Android.support.design.widget.TextInputLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_margin="5dp">
<Android.support.design.widget.TextInputEditText
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:hint="@string/contactLabel"
Android:textSize="16sp" />
</Android.support.design.widget.TextInputLayout>
<Android.support.design.widget.TextInputLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_margin="5dp">
<Android.support.design.widget.TextInputEditText
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:hint="@string/emailLabel"
Android:textSize="16sp" />
</Android.support.design.widget.TextInputLayout>
<Android.support.design.widget.TextInputLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_margin="5dp">
<Android.support.design.widget.TextInputEditText
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:hint="@string/NumberOfEmployee"
Android:textSize="16sp" />
</Android.support.design.widget.TextInputLayout>
</LinearLayout>
</Android.support.v7.widget.CardView>
<Android.support.v7.widget.CardView xmlns:card_view="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_gravity="center"
card_view:cardCornerRadius="5dp"
card_view:cardUseCompatPadding="true">
<TextView
style="@style/group_view_text"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="@drawable/businessdetailtitletextviewbackground"
Android:padding="@dimen/activity_horizontal_margin"
Android:tag="sticky"
Android:text="@string/nature_of_business" />
</Android.support.v7.widget.CardView>
<Android.support.v7.widget.CardView xmlns:card_view="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_gravity="center"
card_view:cardCornerRadius="5dp"
card_view:cardUseCompatPadding="true">
<TextView
style="@style/group_view_text"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="@drawable/businessdetailtitletextviewbackground"
Android:padding="@dimen/activity_horizontal_margin"
Android:tag="sticky"
Android:text="@string/taxation" />
</Android.support.v7.widget.CardView>
</LinearLayout>
</com.lendingkart.prakhar.lendingkartdemo.customview.StickyScrollView>
</LinearLayout>
</layout>
テキストビューのスタイルグループはこれに見えます
<style name="group_view_text" parent="@Android:style/TextAppearance.Medium">
<item name="Android:layout_width">wrap_content</item>
<item name="Android:layout_height">wrap_content</item>
<item name="Android:textColor">@color/edit_text_color</item>
<item name="Android:textSize">16dp</item>
<item name="Android:layout_centerVertical">true</item>
<item name="Android:textStyle">bold</item>
</style>
テキストビューの背景は次のようになります:(@ drawable/businessdetailtitletextviewbackground)
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item>
<shape Android:shape="rectangle">
<solid Android:color="@color/edit_text_color" />
</shape>
</item>
<item Android:bottom="2dp">
<shape Android:shape="rectangle">
<solid Android:color="@color/White" />
</shape>
</item>
</layer-list>
SuperSLiM ライブラリを使用して、この効果に到達できます。ビューの交換可能な線形、グリッド、およびスタッガード表示を備えたRecyclerView用のLayoutManagerを提供します。
良いデモは github repository にあります
単にそのような結果を得るためです
app:slm_headerDisplay="inline|sticky"
or
app:slm_headerDisplay="sticky"
IPhoneのようなリストビューを実現するために、1つの特別なクラスを使用しました。ソースコードの例をこちらで見つけることができます。 https://demonuts.com/Android-recyclerview-sticky-header-like-iphone/
リストビューを更新したこのクラスは
import Android.content.Context;
import Android.graphics.drawable.Drawable;
import Android.util.AttributeSet;
import Android.util.TypedValue;
import Android.view.Gravity;
import Android.view.View;
import Android.view.animation.AlphaAnimation;
import Android.widget.AbsListView;
import Android.widget.AdapterView;
import Android.widget.FrameLayout;
import Android.widget.ImageView;
import Android.widget.ImageView.ScaleType;
import Android.widget.ListView;
import Android.widget.RelativeLayout;
public class HeaderListView extends RelativeLayout {
// TODO: Handle listViews with fast scroll
// TODO: See if there are methods to dispatch to mListView
private static final int FADE_DELAY = 1000;
private static final int FADE_DURATION = 2000;
private InternalListView mListView;
private SectionAdapter mAdapter;
private RelativeLayout mHeader;
private View mHeaderConvertView;
private FrameLayout mScrollView;
private AbsListView.OnScrollListener mExternalOnScrollListener;
public HeaderListView(Context context) {
super(context);
init(context, null);
}
public HeaderListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
mListView = new InternalListView(getContext(), attrs);
LayoutParams listParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
listParams.addRule(ALIGN_PARENT_TOP);
mListView.setLayoutParams(listParams);
mListView.setOnScrollListener(new HeaderListViewOnScrollListener());
mListView.setVerticalScrollBarEnabled(false);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (mAdapter != null) {
mAdapter.onItemClick(parent, view, position, id);
}
}
});
addView(mListView);
mHeader = new RelativeLayout(getContext());
LayoutParams headerParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
headerParams.addRule(ALIGN_PARENT_TOP);
mHeader.setLayoutParams(headerParams);
mHeader.setGravity(Gravity.BOTTOM);
addView(mHeader);
// The list view's scroll bar can be hidden by the header, so we display our own scroll bar instead
Drawable scrollBarDrawable = getResources().getDrawable(R.drawable.scrollbar_handle_holo_light);
mScrollView = new FrameLayout(getContext());
LayoutParams scrollParams = new LayoutParams(scrollBarDrawable.getIntrinsicWidth(), LayoutParams.MATCH_PARENT);
scrollParams.addRule(ALIGN_PARENT_RIGHT);
scrollParams.rightMargin = (int) dpToPx(2);
mScrollView.setLayoutParams(scrollParams);
ImageView scrollIndicator = new ImageView(context);
scrollIndicator.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
scrollIndicator.setImageDrawable(scrollBarDrawable);
scrollIndicator.setScaleType(ScaleType.FIT_XY);
mScrollView.addView(scrollIndicator);
mScrollView.setVisibility(INVISIBLE);
addView(mScrollView);
}
public void setAdapter(SectionAdapter adapter) {
mAdapter = adapter;
mListView.setAdapter(adapter);
}
public void setOnScrollListener(AbsListView.OnScrollListener l) {
mExternalOnScrollListener = l;
}
private class HeaderListViewOnScrollListener implements AbsListView.OnScrollListener {
private int previousFirstVisibleItem = -1;
private int direction = 0;
private int actualSection = 0;
private boolean scrollingStart = false;
private boolean doneMeasuring = false;
private int lastResetSection = -1;
private int nextH;
private int prevH;
private View previous;
private View next;
private AlphaAnimation fadeOut = new AlphaAnimation(1f, 0f);
private boolean noHeaderUpToHeader = false;
private boolean didScroll = false;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (mExternalOnScrollListener != null) {
mExternalOnScrollListener.onScrollStateChanged(view, scrollState);
}
didScroll = true;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (mExternalOnScrollListener != null) {
mExternalOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
}
if (!didScroll) {
return;
}
firstVisibleItem -= mListView.getHeaderViewsCount();
if (firstVisibleItem < 0) {
mHeader.removeAllViews();
return;
}
updateScrollBar();
if (visibleItemCount > 0 && firstVisibleItem == 0 && mHeader.getChildAt(0) == null) {
addSectionHeader(0);
lastResetSection = 0;
}
int realFirstVisibleItem = getRealFirstVisibleItem(firstVisibleItem, visibleItemCount);
if (totalItemCount > 0 && previousFirstVisibleItem != realFirstVisibleItem) {
direction = realFirstVisibleItem - previousFirstVisibleItem;
actualSection = mAdapter.getSection(realFirstVisibleItem);
boolean currIsHeader = mAdapter.isSectionHeader(realFirstVisibleItem);
boolean prevHasHeader = mAdapter.hasSectionHeaderView(actualSection - 1);
boolean nextHasHeader = mAdapter.hasSectionHeaderView(actualSection + 1);
boolean currHasHeader = mAdapter.hasSectionHeaderView(actualSection);
boolean currIsLast = mAdapter.getRowInSection(realFirstVisibleItem) == mAdapter.numberOfRows(actualSection) - 1;
boolean prevHasRows = mAdapter.numberOfRows(actualSection - 1) > 0;
boolean currIsFirst = mAdapter.getRowInSection(realFirstVisibleItem) == 0;
boolean needScrolling = currIsFirst && !currHasHeader && prevHasHeader && realFirstVisibleItem != firstVisibleItem;
boolean needNoHeaderUpToHeader = currIsLast && currHasHeader && !nextHasHeader && realFirstVisibleItem == firstVisibleItem && Math.abs(mListView.getChildAt(0).getTop()) >= mListView.getChildAt(0).getHeight() / 2;
noHeaderUpToHeader = false;
if (currIsHeader && !prevHasHeader && firstVisibleItem >= 0) {
resetHeader(direction < 0 ? actualSection - 1 : actualSection);
} else if ((currIsHeader && firstVisibleItem > 0) || needScrolling) {
if (!prevHasRows) {
resetHeader(actualSection-1);
}
startScrolling();
} else if (needNoHeaderUpToHeader) {
noHeaderUpToHeader = true;
} else if (lastResetSection != actualSection) {
resetHeader(actualSection);
}
previousFirstVisibleItem = realFirstVisibleItem;
}
if (scrollingStart) {
int scrolled = realFirstVisibleItem >= firstVisibleItem ? mListView.getChildAt(realFirstVisibleItem - firstVisibleItem).getTop() : 0;
if (!doneMeasuring) {
setMeasurements(realFirstVisibleItem, firstVisibleItem);
}
int headerH = doneMeasuring ? (prevH - nextH) * direction * Math.abs(scrolled) / (direction < 0 ? nextH : prevH) + (direction > 0 ? nextH : prevH) : 0;
mHeader.scrollTo(0, -Math.min(0, scrolled - headerH));
if (doneMeasuring && headerH != mHeader.getLayoutParams().height) {
LayoutParams p = (LayoutParams) (direction < 0 ? next.getLayoutParams() : previous.getLayoutParams());
p.topMargin = headerH - p.height;
mHeader.getLayoutParams().height = headerH;
mHeader.requestLayout();
}
}
if (noHeaderUpToHeader) {
if (lastResetSection != actualSection) {
addSectionHeader(actualSection);
lastResetSection = actualSection + 1;
}
mHeader.scrollTo(0, mHeader.getLayoutParams().height - (mListView.getChildAt(0).getHeight() + mListView.getChildAt(0).getTop()));
}
}
private void startScrolling() {
scrollingStart = true;
doneMeasuring = false;
lastResetSection = -1;
}
private void resetHeader(int section) {
scrollingStart = false;
addSectionHeader(section);
mHeader.requestLayout();
lastResetSection = section;
}
private void setMeasurements(int realFirstVisibleItem, int firstVisibleItem) {
if (direction > 0) {
nextH = realFirstVisibleItem >= firstVisibleItem ? mListView.getChildAt(realFirstVisibleItem - firstVisibleItem).getMeasuredHeight() : 0;
}
previous = mHeader.getChildAt(0);
prevH = previous != null ? previous.getMeasuredHeight() : mHeader.getHeight();
if (direction < 0) {
if (lastResetSection != actualSection - 1) {
addSectionHeader(Math.max(0, actualSection - 1));
next = mHeader.getChildAt(0);
}
nextH = mHeader.getChildCount() > 0 ? mHeader.getChildAt(0).getMeasuredHeight() : 0;
mHeader.scrollTo(0, prevH);
}
doneMeasuring = previous != null && prevH > 0 && nextH > 0;
}
private void updateScrollBar() {
if (mHeader != null && mListView != null && mScrollView != null) {
int offset = mListView.computeVerticalScrollOffset();
int range = mListView.computeVerticalScrollRange();
int extent = mListView.computeVerticalScrollExtent();
mScrollView.setVisibility(extent >= range ? View.INVISIBLE : View.VISIBLE);
if (extent >= range) {
return;
}
int top = range == 0 ? mListView.getHeight() : mListView.getHeight() * offset / range;
int bottom = range == 0 ? 0 : mListView.getHeight() - mListView.getHeight() * (offset + extent) / range;
mScrollView.setPadding(0, top, 0, bottom);
fadeOut.reset();
fadeOut.setFillBefore(true);
fadeOut.setFillAfter(true);
fadeOut.setStartOffset(FADE_DELAY);
fadeOut.setDuration(FADE_DURATION);
mScrollView.clearAnimation();
mScrollView.startAnimation(fadeOut);
}
}
private void addSectionHeader(int actualSection) {
View previousHeader = mHeader.getChildAt(0);
if (previousHeader != null) {
mHeader.removeViewAt(0);
}
if (mAdapter.hasSectionHeaderView(actualSection)) {
mHeaderConvertView = mAdapter.getSectionHeaderView(actualSection, mHeaderConvertView, mHeader);
mHeaderConvertView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
mHeaderConvertView.measure(MeasureSpec.makeMeasureSpec(mHeader.getWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
mHeader.getLayoutParams().height = mHeaderConvertView.getMeasuredHeight();
mHeaderConvertView.scrollTo(0, 0);
mHeader.scrollTo(0, 0);
mHeader.addView(mHeaderConvertView, 0);
} else {
mHeader.getLayoutParams().height = 0;
mHeader.scrollTo(0, 0);
}
mScrollView.bringToFront();
}
private int getRealFirstVisibleItem(int firstVisibleItem, int visibleItemCount) {
if (visibleItemCount == 0) {
return -1;
}
int relativeIndex = 0, totalHeight = mListView.getChildAt(0).getTop();
for (relativeIndex = 0; relativeIndex < visibleItemCount && totalHeight < mHeader.getHeight(); relativeIndex++) {
totalHeight += mListView.getChildAt(relativeIndex).getHeight();
}
int realFVI = Math.max(firstVisibleItem, firstVisibleItem + relativeIndex - 1);
return realFVI;
}
}
public ListView getListView() {
return mListView;
}
public void addHeaderView(View v) {
mListView.addHeaderView(v);
}
private float dpToPx(float dp) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getContext().getResources().getDisplayMetrics());
}
protected class InternalListView extends ListView {
public InternalListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected int computeVerticalScrollExtent() {
return super.computeVerticalScrollExtent();
}
@Override
protected int computeVerticalScrollOffset() {
return super.computeVerticalScrollOffset();
}
@Override
protected int computeVerticalScrollRange() {
return super.computeVerticalScrollRange();
}
}
}
XMLの使用
<?xml version="1.0" encoding="utf-8"?>
<Android.support.constraint.ConstraintLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.parsaniahardik.listview_stickyheader_ios.HeaderListView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/lv">
</com.example.parsaniahardik.listview_stickyheader_ios.HeaderListView>