java - 使用 Endless RecyclerView 作为日历

标签 java android android-recyclerview

我目前是 Android 开发新手,正在构建我的第一个应用程序。我陷入了一个特别棘手的问题,我正在尝试实现无尽的回收器 View 。

我(当前)使用回收器 View 只是为了获取当前日期并将其显示在日历输出中。有两件事真正阻碍了我。一是没有太多关于在没有数据库的情况下使用无限回收器 View 的文档(我确实计划这样做,但现在又不是),并且不知道在哪里/如何使其无限。我实现的 recyclerView 已经可以工作了,我只需要它不断地加载。我能找到的唯一示例本质上要求我使用数据库,或者在 onCreate 方法中创建一个巨大的方法。我也再次尝试在主类中实现我自己的 setOnScrollListener 但可惜我无法让它工作。

以下是我脑海中想象的期望结果。 Link to UI picture

这是到目前为止我的代码。理想情况下,我希望将滚动监听器保留在 RecyclerAdapter 中,因为稍后我可能会在应用程序的其他方面重用它。提前谢谢您。

家庭类(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;
}

回收器适配器

    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

}

最佳答案

这里有一个想法:在 onCreate 中创建一些基本列表,其中包含回收器 View 当前日期周围的接下来 1000 个日期,并使用以下 link了解如何在任何滚动事件之后找出您在回收器 View 上的位置。一旦接近边缘,只需在范围的这一端添加额外的 1000 个日期即可。

看下面的link了解如何在适配器内部的 recyclerview 上设置 onscrolllistener (基本上您需要将 recyclerview 传递给适配器构造函数)

希望这有帮助

关于java - 使用 Endless RecyclerView 作为日历,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60699858/

相关文章:

android - 取消 RecyclerView 垂直滑动/滑动

java - 当您想要删除重复代码时,如何解决项目的循环依赖?

java - Java 中动态缩进字符串

Java + Hadoop + NoSql(使用什么组合)

android - 从 Google Play 商店中删除应用程序 - 未知的开发者帐户

android - RecyclerView ItemTouchHelper 滑动操作在 fragment 类中不起作用

java - Zookeeper java用户名密码

android - key android :target_state 的 fragment 不再存在

android - 分离 Activity 和 GoogleApiClient 的关注点

android - DiffUtil.ItemCallback 不更新项目位置(删除后)