箭头在哪里?

use*_*117 12 android android-calendar

编辑/注意:我真的需要一个答案,我想继续使用"股票"谷歌Android API.我已经在此创造了+100的赏金,但如果我在接下来的几天内使用股票API得到一个简单的解决方案,我将再增加+100,使其值200点.

我正在尝试使用Android CalendarView控件.我在NestedScrollView中使用按钮和CalendarView制作了一个小应用程序.我做了按钮,它的边距非常大,所以我可以验证滚动工作.在运行Android 6.01的三星Galaxy S5上运行正常.但是在运行4.2.2的三星S Duo(这是我的预定目标)上,没有办法提前一个月(注意当月没有箭头)

这是运行Android 6.01的三星S5的屏幕截图

s5截图

这是三星的Duo运行4.2.2

S Duo截图

content_main.xml看起来像这样...

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <!-- This linear layout is because the scrollview can have only 1 direct child -->
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:orientation="vertical">

        <Button
            android:id="@+id/recordEnd"
            android:layout_width="200dp"
            android:layout_height="100dp"
            android:layout_marginTop="100dp"
            android:layout_marginBottom="100dp"
            android:gravity="center"
            android:text="Record End"/>

        <CalendarView
            android:id="@+id/thecalendar"
            android:layout_width="240dp"
            android:layout_height="300dp"
            android:minDate="01/01/2016"
            android:maxDate="11/30/2016"/>
    </LinearLayout>
</android.support.v4.widget.NestedScrollView>
Run Code Online (Sandbox Code Playgroud)

...在Android Studio中,设计视图确实显示了箭头.我不知道如何调试这个.

Iul*_*scu 10

快速查看CalendarView代码,看起来日历外观是从系统推断的,我无法找到改变它的方法.您可以在下面找到如何选择日历的视图,具体取决于mode:

final TypedArray a = context.obtainStyledAttributes(
        attrs, R.styleable.CalendarView, defStyleAttr, defStyleRes);
final int mode = a.getInt(R.styleable.CalendarView_calendarViewMode, MODE_HOLO);
a.recycle();

switch (mode) {
    case MODE_HOLO:
        mDelegate = new CalendarViewLegacyDelegate(
                this, context, attrs, defStyleAttr, defStyleRes);
        break;
    case MODE_MATERIAL:
        mDelegate = new CalendarViewMaterialDelegate(
                this, context, attrs, defStyleAttr, defStyleRes);
        break;
    default:
        throw new IllegalArgumentException("invalid calendarViewMode attribute");
}
Run Code Online (Sandbox Code Playgroud)

编辑:

花了一些时间在这个问题上我有一些更好的解释:

  1. 预览显示带箭头的视图,因为您尚未设置正确的API版本.如果您看一下下面的图像,您会发现在Lollipop之前的版本中,按钮丢失了,在它之后,一切都很好而且很好.要更改API版本,只需单击红色突出显示的按钮,然后选择所需的API级别,即可在不同平台上准确预览xml.

    KitKat版本 Android N版

  2. 为什么以前版本的Material Design中缺少箭头?在这里,我无法找到谷歌某人给出的答案,但我相信这与屏幕分辨率有某种关系(在较旧的设备上,你没有那么多的空间可以CalendarView在较新的Android版本中显示这就是为什么他们选择了ListView它,因为它只能显示几行并且仍然可以完全正常运行,而显示一个ViewPager将会裁剪一些最后一行).

    正如我在原帖中所说,CalendarView基于Material Design(Android 5.0+)的可用性选择了它的样式.

    旧版本(在下面找到它)有一个ListView和下一个/上一个按钮丢失.因为日历是使用a显示的ListView,所以无法滚动到下个月,因为父视图CalendarView是a Scroll.要解决此问题,您可以在此处找到一些解释和解决方案.

    <TextView android:id="@+android:id/month_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:paddingTop="10dip"
        android:paddingBottom="10dip"
        style="@android:style/TextAppearance.Medium" />
    
     <!-- This is the header representing the days of the week -->
    <LinearLayout android:id="@+android:id/day_names"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="6dip"
        android:layout_marginEnd="2dip"
        android:layout_marginStart="2dip"
        android:gravity="center" >
    
        <TextView android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:visibility="gone" />
    
        <TextView android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center" />
    
        <TextView android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center" />
    
        <TextView android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center" />
    
        <TextView android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center" />
    
        <TextView android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center" />
    
        <TextView android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center" />
    
        <TextView android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center" />
    
    </LinearLayout>
    
    <ImageView android:layout_width="match_parent"
        android:layout_height="1dip"
        android:scaleType="fitXY"
        android:gravity="fill_horizontal"
        android:src="?android:attr/dividerHorizontal" />
    
    <ListView android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:drawSelectorOnTop="false"
        android:cacheColorHint="@android:color/transparent"
        android:fastScrollEnabled="false"
        android:overScrollMode="never" />
    
    Run Code Online (Sandbox Code Playgroud)

    材料设计的版本替换ListViewViewPager,并增加了上一个和下一个按钮.

    <android.widget.DayPickerViewPager
        android:id="@+id/day_picker_view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
    <ImageButton
        android:id="@+id/prev"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:minWidth="48dp"
        android:minHeight="48dp"
        android:src="@drawable/ic_chevron_start"
        android:background="?attr/selectableItemBackgroundBorderless"
        android:contentDescription="@string/date_picker_prev_month_button"
        android:visibility="invisible" />
    
    <ImageButton
        android:id="@+id/next"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:minWidth="48dp"
        android:minHeight="48dp"
        android:src="@drawable/ic_chevron_end"
        android:background="?attr/selectableItemBackgroundBorderless"
        android:contentDescription="@string/date_picker_next_month_button"
        android:visibility="invisible" />
    
    Run Code Online (Sandbox Code Playgroud)

    目前,CalendarView由于stylable从公共API中删除了属性,我无法找到样式.

    android.R.styleable类及其字段已从公共API中删除,以更好地确保应用程序的前向兼容性.

    话虽这么说,你可以保留旧版Android版本的老式风格,因为你无法改变它,但请记住,a ListView不应该在Scroll或试图找到一个稳定的存储库,以满足你的需求.

编辑二:

CalendarView不破,它完美的作品在所有的Android版本,即使,它可能给人的印象是它的行为是因为使用的执行打破ListView.现在,让我们在问题中挖掘一下,这样每个人都可以理解发生了什么:

  1. 问题没有.1:使用ListViewin ScrollView
    一般来说,使用嵌套的元素是一种不好的做法,因为它们无法正确处理滚动操作.

  2. 问题没有.2:使用a NestedScrollView不解决问题
    从Android 5.0谷歌添加了支持库来支持嵌套滚动,但是ListView除非它实现,否则将无法处理滚动NestedScrollingChild.为此,我们将类子ListView类化并实现接口方法,并从每个方法中调用NestedScrollingChildHelper中的相应方法.根据这一步骤,你可以使用ListView一个NestedScrollView,但不是CalendarView(见问题没有.3)

  3. 问题没有.3:您无法更改列表CalendarView
    真正的问题是CalendarView没有任何方法可以让您使用自己编写的自定义列表更改默认列表.假设你有这样一个方法,你可以CalendarView通过用自定义的方法替换默认列表来完成工作,滚动可以完美地工作,但不幸的是你不能.

要解决这个问题,你有两个选择:
- 重新设计你的视图,使其CalendarView不在Scroll名称中包含的类中
- 使用Pravin Divraniya的答案,这将使你的日历工作完美,但请记住,嵌套的卷轴是坏的(特别是在屏幕很小的旧Android设备上


Pra*_*iya 8

Iulian Popescu给出了一个很好的深刻解释,我只想简化它.首先,我想澄清一些事情.

  1. 根据这个官方Android开发人员链接,CalenderView小部件的确切外观和交互模型可能因操作系统版本和主题(例如Holo与Material)而异.
  2. 由于Iulian Popescu粘贴了android.widget.CalendarViewAndroid类的代码,你可以看到CalendarViewLegacyDelegate该类负责在HOLO主题的情况下渲染CalenderView,而CalendarViewMaterialDelegate类负责在MATERIAL主题的情况下渲染CalenderView .我再次发布该代码仅供参考.
public CalendarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        final TypedArray a = context.obtainStyledAttributes(
                attrs, R.styleable.CalendarView, defStyleAttr, defStyleRes);
        final int mode = a.getInt(R.styleable.CalendarView_calendarViewMode, MODE_HOLO);
        a.recycle();
        switch (mode) {
            case MODE_HOLO:
                mDelegate = new CalendarViewLegacyDelegate(
                        this, context, attrs, defStyleAttr, defStyleRes);
                break;
            case MODE_MATERIAL:
                mDelegate = new CalendarViewMaterialDelegate(
                        this, context, attrs, defStyleAttr, defStyleRes);
                break;
            default:
                throw new IllegalArgumentException("invalid calendarViewMode attribute");
        }
    }
Run Code Online (Sandbox Code Playgroud)
  1. CalendarViewMaterialDelegate(android.widget.CalendarViewMaterialDelegate)类中,我们可以看到DayPickerView(android.widget.DayPickerView)类用作渲染我们可以在Material theme中看到的日历视图的容器.用于在一个页面中显示一个月的DayPickerViewViewPager.还有两个ImageButton用于下一个和上一个.由于有两个按钮可以更改月份,因此不会产生任何问题,并且在MATERIAL主题中工作得很好.
    private final ViewPager mViewPager;
    private final ImageButton mPrevButton;
    private final ImageButton mNextButton;
Run Code Online (Sandbox Code Playgroud)

  1. 正如我们在CalendarViewLegacyDelegate(android.widget.CalendarViewLegacyDelegate)类中看到的那样,ListView用于显示周列表(Vertical scrolling)CalenderView.前一个和下一个没有任何ImageButton,因为它将垂直滚动.
/**
     * The adapter for the weeks list.
     */
    private WeeksAdapter mAdapter;

    /**
     * The weeks list.
     */
    private ListView mListView;
Run Code Online (Sandbox Code Playgroud)

根据Android开发者网站的这个链接,我们永远不应该使用ScrollViewa ListView,因为ListView它负责自己的垂直滚动.因此,如果HOLO主题CalenderView在内部使用时会出现意外行为ScrollView.

解:-

您可以使用下面给定的自定义滚动视图类而不是NestedScrollView类.它将使您的CalenderView垂直滚动在HOLO主题的情况下平滑.

public class VerticalScrollView extends ScrollView{

    public VerticalScrollView(Context context) {
        super(context);
    }

    public VerticalScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public VerticalScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        final int action = ev.getAction();
        switch (action)
        {
            case MotionEvent.ACTION_DOWN:
                super.onTouchEvent(ev);
                break;

            case MotionEvent.ACTION_MOVE:
                return false; // redirect MotionEvents to ourself

            case MotionEvent.ACTION_CANCEL:
                super.onTouchEvent(ev);
                break;

            case MotionEvent.ACTION_UP:
                return false;

            default: 
                break;
        }

        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        super.onTouchEvent(ev);
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望这能清除你的疑虑.