ListView
に変更したいと思いRecyclerView
ます。の を使用して、onScroll
ユーザーがリストの最後までスクロールしたかどうかを判断したいと考えています。OnScrollListener
RecyclerView
REST サービスから新しいデータをフェッチできるように、ユーザーがリストの最後までスクロールしたかどうかを知るにはどうすればよいですか?
ListView
に変更したいと思いRecyclerView
ます。の を使用して、onScroll
ユーザーがリストの最後までスクロールしたかどうかを判断したいと考えています。OnScrollListener
RecyclerView
REST サービスから新しいデータをフェッチできるように、ユーザーがリストの最後までスクロールしたかどうかを知るにはどうすればよいですか?
これらの変数を作成します。
private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 5;
int firstVisibleItem, visibleItemCount, totalItemCount;
リサイクラー ビューのスクロールに設定します。
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = mRecyclerView.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached
Log.i("Yaeye!", "end called");
// Do something
loading = true;
}
}
});
注:
LinearLayoutManager
のレイアウト マネージャとして使用していることを確認してくださいRecyclerView
。
LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
およびグリッドの場合
GridLayoutManager mLayoutManager;
mLayoutManager = new GridLayoutManager(getActivity(), spanCount);
mRecyclerView.setLayoutManager(mLayoutManager);
エンドレススクロールを楽しんでください!! ^.^
更新: mRecyclerView。
setOnScrollListener()は非推奨です。置き換えるだけでmRecyclerView.addOnScrollListener()
、警告はなくなります! この SO questionから詳細を読むことができます。
Android が Kotlin を正式にサポートするようになったため、同じものを更新します -
OnScrollListener を作成する
class OnScrollListener(val layoutManager: LinearLayoutManager, val adapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>, val dataList: MutableList<Int>) : RecyclerView.OnScrollListener() {
var previousTotal = 0
var loading = true
val visibleThreshold = 10
var firstVisibleItem = 0
var visibleItemCount = 0
var totalItemCount = 0
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
visibleItemCount = recyclerView.childCount
totalItemCount = layoutManager.itemCount
firstVisibleItem = layoutManager.findFirstVisibleItemPosition()
if (loading) {
if (totalItemCount > previousTotal) {
loading = false
previousTotal = totalItemCount
}
}
if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
val initialSize = dataList.size
updateDataList(dataList)
val updatedSize = dataList.size
recyclerView.post { adapter.notifyItemRangeInserted(initialSize, updatedSize) }
loading = true
}
}
}
このように RecyclerView に追加します
recyclerView.addOnScrollListener(OnScrollListener(layoutManager, adapter, dataList))
完全なコード例については、この Github リポジトリを参照してください。
最後のアイテムが完全に表示されたときにのみ通知を受け取りたい場合は、 を使用できますView.canScrollVertically()
。
これが私の実装です:
public abstract class OnVerticalScrollListener
extends RecyclerView.OnScrollListener {
@Override
public final void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (!recyclerView.canScrollVertically(-1)) {
onScrolledToTop();
} else if (!recyclerView.canScrollVertically(1)) {
onScrolledToBottom();
} else if (dy < 0) {
onScrolledUp();
} else if (dy > 0) {
onScrolledDown();
}
}
public void onScrolledUp() {}
public void onScrolledDown() {}
public void onScrolledToTop() {}
public void onScrolledToBottom() {}
}
注: recyclerView.getLayoutManager().canScrollVertically()
API < 14 をサポートする場合に使用できます。
ここに別のアプローチがあります。任意のレイアウト マネージャーで動作します。
詳細を理解するために、私はブログ投稿とサンプル プロジェクトを書きました 。
MyAdapter.java
public abstract class MyAdapter extends RecyclerView.Adapter<ViewHolder>{
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
//check for last item
if ((position >= getItemCount() - 1))
load();
}
public abstract void load();
}
MyActivity.java
public class MainActivity extends AppCompatActivity {
List<Items> items;
MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
adapter=new MyAdapter(items){
@Override
public void load() {
//implement your load more here
Item lastItem=items.get(items.size()-1);
loadMore();
}
};
}
}
私にとって、それは非常に簡単です:
private boolean mLoading = false;
mList.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int totalItem = mLinearLayoutManager.getItemCount();
int lastVisibleItem = mLinearLayoutManager.findLastVisibleItemPosition();
if (!mLoading && lastVisibleItem == totalItem - 1) {
mLoading = true;
// Scrolled to bottom. Do something here.
mLoading = false;
}
}
});
非同期ジョブには注意してください。非同期ジョブの最後に mLoading を変更する必要があります。それが役立つことを願っています!
ほとんどの回答は、 、 または、または さえRecyclerView
使用することを前提としているか、スクロールが垂直または水平であると想定していますが、完全に一般的な回答を投稿した人はいません。LinearLayoutManager
GridLayoutManager
StaggeredGridLayoutManager
のアダプターを使用するViewHolder
ことは、明らかに良い解決策ではありません。アダプターは、それを使用する複数のアダプターを持つ場合がありRecyclerView
ます。それらの内容を「適応」させます。Recycler View (ユーザーに現在表示されているものを担当する 1 つのクラスであり、にコンテンツを提供することのみを担当するアダプターではRecyclerView
ありません) である必要があります。ロード)。
RecyclerView の抽象化されたクラス (RecycerView.LayoutManager および RecycerView.Adapter) 以外は何も使用しない私のソリューションを次に示します。
/**
* Listener to callback when the last item of the adpater is visible to the user.
* It should then be the time to load more items.
**/
public abstract class LastItemListener extends RecyclerView.OnScrollListener {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// init
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
RecyclerView.Adapter adapter = recyclerView.getAdapter();
if (layoutManager.getChildCount() > 0) {
// Calculations..
int indexOfLastItemViewVisible = layoutManager.getChildCount() -1;
View lastItemViewVisible = layoutManager.getChildAt(indexOfLastItemViewVisible);
int adapterPosition = layoutManager.getPosition(lastItemViewVisible);
boolean isLastItemVisible = (adapterPosition == adapter.getItemCount() -1);
// check
if (isLastItemVisible)
onLastItemVisible(); // callback
}
}
/**
* Here you should load more items because user is seeing the last item of the list.
* Advice: you should add a bollean value to the class
* so that the method {@link #onLastItemVisible()} will be triggered only once
* and not every time the user touch the screen ;)
**/
public abstract void onLastItemVisible();
}
// --- Exemple of use ---
myRecyclerView.setOnScrollListener(new LastItemListener() {
public void onLastItemVisible() {
// start to load more items here.
}
}
受け入れられた答えは完全に機能しますが、setOnScrollListener は非推奨であるため、以下のソリューションでは addOnScrollListener を使用し、変数の数と if 条件を減らします。
final LinearLayoutManager layoutManager = new LinearLayoutManager(context);
feedsRecyclerView.setLayoutManager(layoutManager);
feedsRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
if ((layoutManager.getChildCount() + layoutManager.findFirstVisibleItemPosition()) >= layoutManager.getItemCount()) {
Log.d("TAG", "End of list");
//loadMore();
}
}
}
});
この質問には非常に多くの答えがありますが、エンドレス リスト ビューを作成した経験を共有したいと思います。最近、リストを無限にスクロールするだけでなく、特定のポイントまでスクロールすることで、サイクルで機能するカスタム Carousel LayoutManager を実装しました。GitHubの詳細な説明は次のとおりです。
カスタム LayoutManager の作成に関する短いが貴重な推奨事項を記載したこの記事をご覧になることをお勧めします: http://cases.azoft.com/create-custom-layoutmanager-android/
recyclerList.setOnScrollListener(new RecyclerView.OnScrollListener()
{
@Override
public void onScrolled(RecyclerView recyclerView, int dx,int dy)
{
super.onScrolled(recyclerView, dx, dy);
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView,int newState)
{
int totalItemCount = layoutManager.getItemCount();
int lastVisibleItem = layoutManager.findLastVisibleItemPosition();
if (totalItemCount> 1)
{
if (lastVisibleItem >= totalItemCount - 1)
{
// End has been reached
// do something
}
}
}
});
LayoutManager
使用済み(例: )を拡張し、メソッドLinearLayoutManager
をオーバーライドしようとします。scrollVerticallyBy()
まず、最初に呼び出しsuper
てから、返された整数値を確認します。値が等しい場合0
、下または上の境界に達しています。次に、findLastVisibleItemPosition()
メソッドを使用して到達した境界を見つけ、必要に応じてさらにデータをロードします。ただのアイデア。
さらに、そのメソッドから値を返すこともでき、オーバースクロールを許可し、「読み込み中」インジケーターを表示できます。
このpaginateという名前の使いやすいライブラリがあります。ListView と RecyclerView ( LinearLayout 、 GridLayout 、 StaggeredGridLayout ) の両方をサポートします。
ここにGithubのプロジェクトへのリンクがあります
クラスのonBindViewHolder
メソッドでこのロジックを使用して、無限スクロール型の実装を実現しました。RecyclerView.Adapter
if (position == mItems.size() - 1 && mCurrentPage <= mTotalPageCount) {
if (mCurrentPage == mTotalPageCount) {
mLoadImagesListener.noMorePages();
} else {
int newPage = mCurrentPage + 1;
mLoadImagesListener.loadPage(newPage);
}
}
このコードを使用すると、RecyclerView が最後のアイテムに到達すると、現在のページがインクリメントされ、API からより多くのデータをロードして新しい結果をアダプターに追加するインターフェイスでコールバックが行われます。
これが明確でない場合は、より完全な例を投稿できますか?
ここでStaggeredGridLayoutManagerを使用する人にとっては、私の実装であり、私にとってはうまくいきます。
private class ScrollListener extends RecyclerView.OnScrollListener {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
firstVivisibleItems = mLayoutManager.findFirstVisibleItemPositions(firstVivisibleItems);
if(!recyclerView.canScrollVertically(1) && firstVivisibleItems[0]!=0) {
loadMoreImages();
}
}
private boolean loadMoreImages(){
Log.d("myTag", "LAST-------HERE------");
return true;
}
}
RecyclerView を使用してページ分割する方法のかなり詳細な例があります。大まかに言えば、私は PAGE_SIZE を 30 に設定しています。つまり、30 個のアイテムをリクエストし、30 個返されたら次のページをリクエストします。取得したアイテムが 30 未満の場合は、変数にフラグを立てて最後のページに到達したことを示し、それ以上のページの要求を停止します。それをチェックして、あなたの考えを教えてください。
https://medium.com/@etiennelawlor/pagination-with-recyclerview-1cb7e66a502b
ここで、Web でAsyncListUtilを使用する私のソリューションは次のように述べています。しかし、私は odata を使用してデータを読み取り、正常に動作しています。私の例のデータ エンティティとネットワーク メソッドが欠落しています。サンプル アダプターのみを含めます。
public class AsyncPlatoAdapter extends RecyclerView.Adapter {
private final AsyncPlatoListUtil mAsyncListUtil;
private final MainActivity mActivity;
private final RecyclerView mRecyclerView;
private final String mFilter;
private final String mOrderby;
private final String mExpand;
public AsyncPlatoAdapter(String filter, String orderby, String expand, RecyclerView recyclerView, MainActivity activity) {
mFilter = filter;
mOrderby = orderby;
mExpand = expand;
mRecyclerView = recyclerView;
mActivity = activity;
mAsyncListUtil = new AsyncPlatoListUtil();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).
inflate(R.layout.plato_cardview, parent, false);
// Create a ViewHolder to find and hold these view references, and
// register OnClick with the view holder:
return new PlatoViewHolderAsync(itemView, this);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Plato item = mAsyncListUtil.getItem(position);
PlatoViewHolderAsync vh = (PlatoViewHolderAsync) holder;
if (item != null) {
Integer imagen_id = item.Imagen_Id.get();
vh.getBinding().setVariable(BR.plato, item);
vh.getBinding().executePendingBindings();
vh.getImage().setVisibility(View.VISIBLE);
vh.getProgress().setVisibility(View.GONE);
String cacheName = null;
String urlString = null;
if (imagen_id != null) {
cacheName = String.format("imagenes/imagen/%d", imagen_id);
urlString = String.format("%s/menusapi/%s", MainActivity.ROOTPATH, cacheName);
}
ImageHelper.downloadBitmap(mActivity, vh.getImage(), vh.getProgress(), urlString, cacheName, position);
} else {
vh.getBinding().setVariable(BR.plato, item);
vh.getBinding().executePendingBindings();
//show progress while loading.
vh.getImage().setVisibility(View.GONE);
vh.getProgress().setVisibility(View.VISIBLE);
}
}
@Override
public int getItemCount() {
return mAsyncListUtil.getItemCount();
}
public class AsyncPlatoListUtil extends AsyncListUtil<Plato> {
/**
* Creates an AsyncListUtil.
*/
public AsyncPlatoListUtil() {
super(Plato.class, //my data class
10, //page size
new DataCallback<Plato>() {
@Override
public int refreshData() {
//get count calling ../$count ... odata endpoint
return countPlatos(mFilter, mOrderby, mExpand, mActivity);
}
@Override
public void fillData(Plato[] data, int startPosition, int itemCount) {
//get items from odata endpoint using $skip and $top
Platos p = loadPlatos(mFilter, mOrderby, mExpand, startPosition, itemCount, mActivity);
for (int i = 0; i < Math.min(itemCount, p.value.size()); i++) {
data[i] = p.value.get(i);
}
}
}, new ViewCallback() {
@Override
public void getItemRangeInto(int[] outRange) {
//i use LinearLayoutManager in the RecyclerView
LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
outRange[0] = layoutManager.findFirstVisibleItemPosition();
outRange[1] = layoutManager.findLastVisibleItemPosition();
}
@Override
public void onDataRefresh() {
mRecyclerView.getAdapter().notifyDataSetChanged();
}
@Override
public void onItemLoaded(int position) {
mRecyclerView.getAdapter().notifyItemChanged(position);
}
});
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
onRangeChanged();
}
});
}
}
}
@kushal @abdulaziz
代わりにこのロジックを使用してみませんか?
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
int totalItemCount, lastVisibleItemPosition;
if (dy > 0) {
totalItemCount = _layoutManager.getItemCount();
lastVisibleItemPosition = _layoutManager.findLastVisibleItemPosition();
if (!_isLastItem) {
if ((totalItemCount - 1) == lastVisibleItemPosition) {
LogUtil.e("end_of_list");
_isLastItem = true;
}
}
}
}
すべてが詳細に説明されていることを確認してください: RecyclerView From A to Z を使用したページネーション
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView,
int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = mLayoutManager.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
int firstVisibleItemPosition = mLayoutManager.findFirstVisibleItemPosition();
if (!mIsLoading && !mIsLastPage) {
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount
&& firstVisibleItemPosition >= 0) {
loadMoreItems();
}
}
}
})
loadMoreItems():
private void loadMoreItems() {
mAdapter.removeLoading();
//load data here from the server
// in case of success
mAdapter.addData(data);
// if there might be more data
mAdapter.addLoading();
}
MyAdapter で:
private boolean mIsLoadingFooterAdded = false;
public void addLoading() {
if (!mIsLoadingFooterAdded) {
mIsLoadingFooterAdded = true;
mLineItemList.add(new LineItem());
notifyItemInserted(mLineItemList.size() - 1);
}
}
public void removeLoading() {
if (mIsLoadingFooterAdded) {
mIsLoadingFooterAdded = false;
int position = mLineItemList.size() - 1;
LineItem item = mLineItemList.get(position);
if (item != null) {
mLineItemList.remove(position);
notifyItemRemoved(position);
}
}
}
public void addData(List<YourDataClass> data) {
for (int i = 0; i < data.size(); i++) {
YourDataClass yourDataObject = data.get(i);
mLineItemList.add(new LineItem(yourDataObject));
notifyItemInserted(mLineItemList.size() - 1);
}
}
以下を試してください:
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.LayoutManager;
/**
* Abstract Endless ScrollListener
*
*/
public abstract class EndlessScrollListener extends
RecyclerView.OnScrollListener {
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 10;
// The current offset index of data you have loaded
private int currentPage = 1;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;
// The total number of items in the data set after the last load
private int previousTotal = 0;
private int firstVisibleItem;
private int visibleItemCount;
private int totalItemCount;
private LayoutManager layoutManager;
public EndlessScrollListener(LayoutManager layoutManager) {
validateLayoutManager(layoutManager);
this.layoutManager = layoutManager;
}
public EndlessScrollListener(int visibleThreshold,
LayoutManager layoutManager, int startPage) {
validateLayoutManager(layoutManager);
this.visibleThreshold = visibleThreshold;
this.layoutManager = layoutManager;
this.currentPage = startPage;
}
private void validateLayoutManager(LayoutManager layoutManager)
throws IllegalArgumentException {
if (null == layoutManager
|| !(layoutManager instanceof GridLayoutManager)
|| !(layoutManager instanceof LinearLayoutManager)) {
throw new IllegalArgumentException(
"LayoutManager must be of type GridLayoutManager or LinearLayoutManager.");
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = recyclerView.getChildCount();
totalItemCount = layoutManager.getItemCount();
if (layoutManager instanceof GridLayoutManager) {
firstVisibleItem = ((GridLayoutManager) layoutManager)
.findFirstVisibleItemPosition();
} else if (layoutManager instanceof LinearLayoutManager) {
firstVisibleItem = ((LinearLayoutManager) layoutManager)
.findFirstVisibleItemPosition();
}
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading
&& (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
// End has been reached do something
currentPage++;
onLoadMore(currentPage);
loading = true;
}
}
// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page);
}
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#setOnScrollListener%28android.support.v7.widget.RecyclerView.OnScrollListener%29にメソッドpublic void setOnScrollListener (RecyclerView.OnScrollListener listener)
があります。それを使って
編集:
onScrollStateChanged
内のメソッドをオーバーライドonScrollListener
して、これを行います
boolean loadMore = firstVisibleItem + visibleItemCount >= totalItemCount;
//loading is used to see if its already loading, you have to manually manipulate this boolean variable
if (loadMore && !loading) {
//end of list reached
}
リストが小さすぎるかどうかを考慮した回答はありません。
これは、RecycleViews で両方向に機能する、私が使用しているコードの一部です。
@Override
public boolean onTouchEvent(MotionEvent motionEvent) {
if (recyclerViewListener == null) {
return super.onTouchEvent(motionEvent);
}
/**
* If the list is too small to scroll.
*/
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
if (!canScrollVertically(1)) {
recyclerViewListener.reachedBottom();
} else if (!canScrollVertically(-1)) {
recyclerViewListener.reachedTop();
}
}
return super.onTouchEvent(motionEvent);
}
public void setListener(RecyclerViewListener recycleViewListener) {
this.recyclerViewListener = recycleViewListener;
addOnScrollListener(new OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (recyclerViewListener == null) {
return;
}
recyclerViewListener.scrolling(dy);
if (!canScrollVertically(1)) {
recyclerViewListener.reachedBottom();
} else if (!canScrollVertically(-1)) {
recyclerViewListener.reachedTop();
}
}
});
}
私はちょうどこれを試しました:
final LinearLayoutManager rvLayoutManager = new LinearLayoutManager(this);
rvMovieList = (RecyclerView) findViewById(R.id.rvMovieList);
rvMovieList.setLayoutManager(rvLayoutManager);
adapter = new MovieRecyclerAdapter(this, movies);
rvMovieList.setAdapter(adapter);
adapter.notifyDataSetChanged();
rvMovieList.addOnScrollListener(new OnScrollListener() {
boolean loading = true;
int pastVisiblesItems, visibleItemCount, totalItemCount;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = rvLayoutManager.getChildCount();
totalItemCount = rvLayoutManager.getItemCount();
pastVisiblesItems = rvLayoutManager.findFirstVisibleItemPosition();
int lastitem = visibleItemCount + pastVisiblesItems;
if ( lastitem == totalItemCount
&& page < total_pages
&& !keyword.equals("") ) {
// hit bottom ..
String strnext;
if (page == total_pages - 1) {
int last = total_results - (page * 20);
strnext = String.format(getResources().getString(R.string.next), last);
} else {
strnext = String.format(getResources().getString(R.string.next), 20);
}
btNext.setText(strnext);
btNext.setVisibility(View.VISIBLE);
} else {
btNext.setVisibility(View.INVISIBLE);
}
if(pastVisiblesItems == 0 && page > 1){
// hit top
btPrev.setVisibility(View.VISIBLE);
} else {
btPrev.setVisibility(View.INVISIBLE);
}
}
});
orloading
をどこに置くべきか混乱したので、それを削除しようとすると、このコードは期待どおりに機能します。true
false