标题翻译
Using an Endless RecyclerView as a Calendar
问题
以下是您提供的代码的翻译:
我目前刚接触Android开发,正在构建我的第一个应用程序。我在一个特别棘手的部分卡住了,我试图实现一个无限滚动的可循环视图(Endless Recycler View)。
我目前使用一个RecyclerView仅仅是为了获取当前日期并在日历输出中显示它们。有两个问题让我困扰。首先,在没有数据库的情况下使用无限滚动的RecyclerView几乎没有太多文档(我确实打算以后使用数据库,但现在还不打算),而且不知道在哪里/如何使其无限滚动。我已经实现的RecyclerView已经可以工作,我只需要它能够无限加载。我能找到的唯一的示例要么要求我使用数据库,要么就是在onCreate方法中创建一个庞大的方法。此外,我还尝试在主类中实现了自己的setOnScrollListener,但是遗憾的是,我无法使其工作。
下面是我头脑中想象的期望结果。
[UI图片链接][1]
以下是迄今为止的代码。理想情况下,我希望将onScroll监听器保留在RecyclerAdapter中,因为我可能会在应用程序的其他方面重用它。非常感谢您的提前帮助。
主类(HOME CLASS)
public class Home extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
private static final String TAG = "主类(Home Class)";
//RecyclerView变量和myCalendarClass变量
private myCalendarClass myCalendarObj;
private int weeksInView = 1; //将需要根据用户切换视图时更新此值为动态值
private ArrayList<Calendar> calendarArrayList = new ArrayList<>();
private ArrayList<Integer> iconList = new ArrayList<>();
private ArrayList<Integer> eventCounterList = new ArrayList<>();
//RecyclerView动态加载变量
private RecyclerView calendarRecyclerView;
private boolean isLoading = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
initializeNavMenuButtons();
setViewSpinner();
this.myCalendarObj = new myCalendarClass();
setAllCalendarFields(this.myCalendarObj);
getImagesAndEventCounters();
//用户切换视图时调用方法的示例顺序
//setCalendarItrToCurrentSunday();
//setCalendarArrayList();
//getImagesAndEventCounters();
}
//RecyclerView代码
//获取图像和事件以供填充RecyclerView
private void getImagesAndEventCounters() {
Log.d(TAG, "initImageBitMaps: 被调用");
ArrayList<Calendar> weekView = getCalendarArrayList();
int daysInView = this.weeksInView * 7;
System.out.println("视图中的天数:" + daysInView + " 视图中的周数:" + this.weeksInView);
for (int i = 0; i < daysInView; i++) {
calendarArrayList.add(weekView.get(i));
iconList.add(R.id.fitnessIcon);
eventCounterList.add(R.string.XEventsDefault);
iconList.add(R.id.educationIcon);
eventCounterList.add(R.string.XEventsDefault);
iconList.add(R.id.workIcon);
eventCounterList.add(R.string.XEventsDefault);
iconList.add(R.id.personalIcon);
eventCounterList.add(R.string.XEventsDefault);
initRecyclerView();
}
}
//将数据传递给父RecyclerView并设置视图
private void initRecyclerView() {
//对于一个RecyclerView
this.parentLayoutManager = new GridLayoutManager(this, 7);
//GridLayoutManager layoutManager = parentLayoutManager;
RecyclerView recyclerView = findViewById(R.id.calendarRecyclerView);
recyclerView.setLayoutManager(parentLayoutManager);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, iconList, eventCounterList, weeksInView, calendarArrayList);
recyclerView.setAdapter(adapter);
}
//视图选择器(下拉菜单)
private void setViewSpinner(){
Spinner viewSpinner = findViewById(R.id.ViewDropDownButton);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.Calendar_View_List, android.R.layout.simple_spinner_item);
viewSpinner.setAdapter(adapter);
viewSpinner.setOnItemSelectedListener(this);
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String text = parent.getItemAtPosition(position).toString();
myCalendarClass myCalendarObj;
if(text.equals("周视图")){
myCalendarObj = new myCalendarClass("Week View");
setAllCalendarFields(myCalendarObj);
getImagesAndEventCounters();
this.myCalendarObj = myCalendarObj;
}
else if (text.equals("双周视图")){
myCalendarObj = new myCalendarClass("Biweekly View");
setAllCalendarFields(myCalendarObj);
getImagesAndEventCounters();
this.myCalendarObj = myCalendarObj;
}
else if (text.equals("月视图")){
myCalendarObj = new myCalendarClass("Month View");
setAllCalendarFields(myCalendarObj);
getImagesAndEventCounters();
this.myCalendarObj = myCalendarObj;
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
//设置器(setters)
//设置从myCalendarClass需要的所有本地变量
private void setAllCalendarFields(myCalendarClass c){
this.myCalendarObj = c;
this.calendarArrayList = c.getCalendarArrayList();
this.weeksInView = c.getWeeksInView();
}
//获取器(getters)
//返回日历ArrayList
private ArrayList<Calendar> getCalendarArrayList(){
return this.calendarArrayList;
}
适配器(RECYCLER ADAPTER)
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private static final String TAG = "RecyclerViewAdapter";
//用于创建RecyclerView卡片的变量
private ArrayList<Integer> iconList;
private ArrayList<Integer> eventCounterList;
private Context mContext;
private int itemCount;
private ArrayList<Calendar> calendarArrayList;
private ArrayList<String> dayStr;
private ArrayList<String> dayNum;
public RecyclerViewAdapter(Context context, ArrayList<Integer> imageList, ArrayList<Integer> eventArray, int weeksInView, ArrayList<Calendar> calendarArrayList){
this.iconList = imageList;
this.eventCounterList = eventArray;
this.mContext = context;
this.itemCount = weeksInView * 7;
this.calendarArrayList = calendarArrayList;
setDayStrNDayNum();
}
<details>
<summary>英文翻译</summary>
I'm currently new to android development and I'm in the process of building my first app. I'm stuck on a particular tricky bit in which I'm trying to implement and Endless Recycler View.
I'm using a recycler view (currently) just to get the current dates and display them in a calendar output. There is two things that are really holding me up. One there is not much documentation out there on using an endless recycler view without a database (I do plan to but again not right now), and not knowing where/how to make it endless. The recyclerView I have Implemented is already working I just need it to load endlessly. The only examples I could find essentially required me to be using a database, or were to create one gigantic method in the onCreate method. Again I have also tried to implement my own setOnScrollListener inside the home class but alas I couldn't get it working.
Below are the desired results that I've got pictured in my head.
[Link to UI picture][1]
Here is my code so far. Ideally I would like to keep the on scroll Listener in the RecyclerAdapter as I will probably reuse it later on in other aspects of the app. Thank you in advanced.
HOME CLASS
public class Home extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
private static final String TAG = "Home Class" ;
//Recycler View Variables and myCalendarClass Variables
private myCalendarClass myCalendarObj;
private int weeksInView = 1; //will need to make this update dynamicallly based on when a user toggles the view
private ArrayList<Calendar> calendarArrayList = new ArrayList<>();
private ArrayList<Integer> iconList = new ArrayList<>();
private ArrayList<Integer> eventCounterList = new ArrayList<>();
//recycler view dynamic loading variables
private RecyclerView calendarRecyclerView;
private boolean isLoading = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
initializeNavMenuButtons();
setViewSpinner();
this.myCalendarObj = new myCalendarClass();
setAllCalendarFields(this.myCalendarObj);
getImagesAndEventCounters();
//Example of the order to call the methods when a user switches the view
//setCalendarItrToCurrentSunday();
//setCalendarArrayList();
//getImagesAndEventCounters();
}
//Recycler view code
//gets images and events to feed into the recycler view
private void getImagesAndEventCounters() {
Log.d(TAG, "initImageBitMaps: called");
ArrayList<Calendar> weekView = getCalendarArrayList();
int daysInView = this.weeksInView * 7;
System.out.println("Days in view " + daysInView + " Weeks In View " + this.weeksInView);
for (int i = 0; i < daysInView; i++) {
calendarArrayList.add(weekView.get(i));
iconList.add(R.id.fitnessIcon);
eventCounterList.add(R.string.XEventsDefault);
iconList.add(R.id.educationIcon);
eventCounterList.add(R.string.XEventsDefault);
iconList.add(R.id.workIcon);
eventCounterList.add(R.string.XEventsDefault);
iconList.add(R.id.personalIcon);
eventCounterList.add(R.string.XEventsDefault);
initRecyclerView();
}
}
//passes data to the parent recycler view and sets the view
private void initRecyclerView() {
//For one recyclerView
this.parentLayoutManager = new GridLayoutManager(this, 7);
//GridLayoutManager layoutManager = parentLayoutManager;
RecyclerView recyclerView = findViewById(R.id.calendarRecyclerView);
recyclerView.setLayoutManager(parentLayoutManager);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this,iconList,eventCounterList,weeksInView,calendarArrayList);
recyclerView.setAdapter(adapter);
//ViewSpinner(Drop Down Menu)
private void setViewSpinner(){
Spinner viewSpinner = findViewById(R.id.ViewDropDownButton);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.Calendar_View_List, android.R.layout.simple_spinner_item);
viewSpinner.setAdapter(adapter);
viewSpinner.setOnItemSelectedListener(this);
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String text = parent.getItemAtPosition(position).toString();
myCalendarClass myCalendarObj;
if(text.equals("Week View")){
myCalendarObj = new myCalendarClass("Week View");
setAllCalendarFields(myCalendarObj);
getImagesAndEventCounters();
this.myCalendarObj = myCalendarObj;
}
else if (text.equals("Biweekly View")){
myCalendarObj = new myCalendarClass("Biweekly View");
setAllCalendarFields(myCalendarObj);
getImagesAndEventCounters();
this.myCalendarObj = myCalendarObj;
}
else if (text.equals("Month View")){
myCalendarObj = new myCalendarClass("Month View");
setAllCalendarFields(myCalendarObj);
getImagesAndEventCounters();
this.myCalendarObj = myCalendarObj;
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
//setters
//sets all the local variables needed from myCalendarClass
private void setAllCalendarFields(myCalendarClass c){
this.myCalendarObj = c;
this.calendarArrayList = c.getCalendarArrayList();
this.weeksInView = c.getWeeksInView();
}
//getters
//returns the calendar arraylist
private ArrayList<Calendar> getCalendarArrayList(){
return this.calendarArrayList;
}
RECYCLER ADAPTER
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private static final String TAG = "RecyclerViewAdapter";
//variables for creating the recyclerView cards
private ArrayList<Integer> iconList;
private ArrayList<Integer> eventCounterList;
private Context mContext;
private int itemCount;
private ArrayList<Calendar> calendarArrayList;
private ArrayList<String> dayStr;
private ArrayList<String> dayNum;
public RecyclerViewAdapter(Context context, ArrayList<Integer> imageList, ArrayList<Integer> eventArray, int weeksInView,ArrayList<Calendar> calendarArrayList){
this.iconList = imageList;
this.eventCounterList = eventArray;
this.mContext = context;
this.itemCount = weeksInView*7;
this.calendarArrayList = calendarArrayList;
setDayStrNDayNum();
}
@NonNull
@Override
//this is the method that actually inflates each individual layout
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Log.d(TAG, "onCreateViewHolder: called.");
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_listitem,parent,false);
return new ViewHolder(view);
}
@Override
//this is where we bind the data to each individual list items
//essentially all the data and stuff is actually attached in this method to each indiviual list item
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder: called");
holder.fitnessIcon.getDrawable();
holder.educationIcon.getDrawable();
holder.personalIcon.getDrawable();
holder.workIcon.getDrawable();
holder.fitnessEventCounter.setText(eventCounterList.get(position));
holder.educationEventCounter.setText(eventCounterList.get(position));
holder.workEventCounter.setText(eventCounterList.get(position));
holder.personalEventCounter.setText(eventCounterList.get(position));
holder.dayString.setText(dayStr.get(position));
holder.dayNum.setText(dayNum.get(position));
}
//returns the amount of items we wish to include in the recycler view (not the individual items within a card layout
// but instead how many cards we wish to include...probably
@Override
public int getItemCount() {
return itemCount;
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView fitnessIcon;
ImageView educationIcon;
ImageView workIcon;
ImageView personalIcon;
TextView dayString;
TextView dayNum;
TextView fitnessEventCounter;
TextView educationEventCounter;
TextView workEventCounter;
TextView personalEventCounter;
public ViewHolder(View itemView){
super(itemView);
//icons within the layout_listitem
fitnessIcon = itemView.findViewById(R.id.fitnessIcon);
educationIcon = itemView.findViewById(R.id.educationIcon);
workIcon = itemView.findViewById(R.id.workIcon);
personalIcon = itemView.findViewById(R.id.personalIcon);
//text fields within the layout_listitem
dayNum = itemView.findViewById(R.id.dayNum);
dayString = itemView.findViewById(R.id.dayStr);
fitnessEventCounter = itemView.findViewById(R.id.fitnessEventCounter);
educationEventCounter = itemView.findViewById(R.id.educationEventCounter);
workEventCounter = itemView.findViewById(R.id.workEventCounter);
personalEventCounter = itemView.findViewById(R.id.personalEventCounter);
}
}
public void setItemCount(int newItemCount){
itemCount = newItemCount;
}
//sets the dayStr arrays and the dayNum array using CalendarArrayList
// to pull the day in the month and the string value(monday,tuesday,etc.)
private void setDayStrNDayNum(){
Iterator<Calendar> itr = this.calendarArrayList.iterator();
ArrayList<String> tempDayNum = new ArrayList<>();
ArrayList<String> tempDayStr = new ArrayList<>();
int i = 0;
while(itr.hasNext()){
String dayInMonth = getDayInMonth(calendarArrayList.get(i));
String weekDayToString = weekDayToString(calendarArrayList.get(i));
tempDayNum.add(dayInMonth);
tempDayStr.add(weekDayToString);
i++;
itr.next();
}//while
this.dayNum = tempDayNum;
this.dayStr = tempDayStr;
}
//takes in a Calendar Obj, gets the int, and returns it in a String Format
private String getDayInMonth (Calendar c){
Integer temp = c.get(Calendar.DAY_OF_MONTH);
String answer = Integer.toString(temp);
return answer;
}
//takes in a Calendar Obj, gets the weekday digit from 1 to 7, and returns a String
// 1 being Su for Sunday, 2 Mo for Monday, and etc.
private String weekDayToString (Calendar x){
int temp = x.get(Calendar.DAY_OF_WEEK);
switch(temp){
case 1:
return "Su";
case 2:
return "Mo";
case 3:
return "Tu";
case 4:
return "We";
case 5:
return "Th";
case 6:
return "Fr";
case 7:
return "Sa";
}
return "null";
}//weekDayToString
}
[1]: https://i.stack.imgur.com/cQimI.png
</details>
# 答案1
**得分**: 0
这里有一个想法:在onCreate中创建一个包含当前日期附近的未来1000个日期的基本列表,用于您的RecyclerView,并使用以下链接[1]来了解如何在任何滚动事件后找出您在RecyclerView上的位置。一旦您靠近边缘,只需在该光谱的末端添加额外的1000个日期。
查看以下链接[2],了解如何在适配器内部为RecyclerView设置一个onscrolllistener(基本上您需要将RecyclerView传递给适配器的构造函数)
希望这对您有所帮助
[1]: https://stackoverflow.com/a/25053500/10637400
[2]: https://stackoverflow.com/questions/31000964/how-to-implement-setonscrolllistener-in-recyclerview
<details>
<summary>英文翻译</summary>
here is an idea: in onCreate create some base list containing the next 1000 dates surrounding the current date for your recyclerview and use the following [link][1] to understand how to find out after any scrollevent at which position you are on the recyclerview. once you get close to the edges simply add an additional 1000 dates on that end of the spectrum.
Look at the following [link][2] to see how to set an onscrolllistener on a recyclerview inside of the adapter (basically you need to pass the recyclerview to the adapters constructor)
hope this helps
[1]: https://stackoverflow.com/a/25053500/10637400
[2]: https://stackoverflow.com/questions/31000964/how-to-implement-setonscrolllistener-in-recyclerview
</details>
专注分享java语言的经验与见解,让所有开发者获益!
评论