我正在Xamarin Android(基于this tutorial)上创建自己的日历.我将Java所需的所有内容都转换为C#,但是现在当我启动应用程序并打开行中包含自定义日历的片段时:
public overrIDe VIEw OnCreateVIEw(LayoutInflater inflater, VIEwGroup container, Bundle savedInstanceState) { var vIEw = inflater.Inflate(Resource.Layout.calendar_fragment_main, container, false); //System.NotSupportedException Error return vIEw;}
我收到一个错误消息:
System.NotSupportedException – Could not activate JNI Handle 0xffcdb7e8 (key_handle 0x741b240) of Java type ‘md57f15d2d0137b5b5d70f719ce3cee21d4/EstiCalendar’ as managed type ‘EstiMOBILE.DroID.Components.EstiCalendar.Component.Layouts.EstiCalendar’.
还有另外两个错误,可能是第一个错误指出:
java.lang.UnsupportedOperationException – Binary XML file line #1: You must supply a layout_wIDth attribute.
AndroID.VIEws.InflateException – Binary XML file line #1: Binary XML file line #1: You must supply a layout_wIDth attribute.
包含自定义日历的片段(calendar_fragment_main.axml):
<?xml version="1.0" enCoding="utf-8"?><relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:esticalendar="http://schemas.androID.com/apk/res-auto" xmlns:app="http://schemas.androID.com/apk/res-auto" xmlns:tools="http://schemas.androID.com/tools" androID:orIEntation="vertical" androID:layout_wIDth="match_parent" androID:layout_height="match_parent"> <relativeLayout androID:ID="@+ID/calendar_content_wrapper" androID:orIEntation="vertical" androID:layout_wIDth="match_parent" androID:layout_height="match_parent"> <TextVIEw androID:ID="@+ID/calendar_Title" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:layout_alignParenttop="true" tools:text="Calendar" /> <CalendarVIEw androID:layout_wIDth="fill_parent" androID:layout_height="fill_parent" androID:layout_below="@ID/calendar_Title" androID:ID="@+ID/calendar_main_object" androID:visibility="gone" /> <EstiMOBILE.DroID.Components.EstiCalendar.Component.Layouts.EstiCalendar androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:ID="@+ID/esti_calendar" esticalendar:date_format="MMMM yyyy" /> </relativeLayout></relativeLayout>
我的自定义日历类EstiCalendar.cs
using System;using System.Collections.Generic;using AndroID.Content;using AndroID.Content.Res;using AndroID.Graphics;using AndroID.Runtime;using AndroID.Util;using AndroID.VIEws;using AndroID.Widget;using Java.Text;using Java.Util;namespace EstiMOBILE.DroID.Components.EstiCalendar.Component.Layouts{ public class EstiCalendar : linearLayout { // how many days to show, defaults to six weeks, 42 days private static Readonly int DAYS_COUNT = 42; // default date format private static Readonly string DATE_FORMAT = "MMM yyyy"; // date format private string dateFormat; // current displayed month private Calendar currentDate = Calendar.Instance; //event handling private IEventHandler eventHandler = null; // internal components private linearLayout header; private ImageVIEw btnPrev; private ImageVIEw btnNext; private TextVIEw txtDate; private GrIDVIEw grID; // seasons' rainbow int[] rainbow = new int[] { Resource.color.summer, Resource.color.fall, Resource.color.winter, Resource.color.spring }; // month-season association (northern hemisphere, sorry australia :) Readonly int[] monthSeason = { 2, 2, 3, 3, 3, 0, 0, 0, 1, 1, 1, 2 }; public EstiCalendar(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer) { } public EstiCalendar(Context context, IAttributeSet attrs) : base(context, attrs) { InitControl(context, attrs); } public EstiCalendar(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr) { InitControl(context, attrs); } /** * Load control xml layout */ private voID InitControl(Context context, IAttributeSet attrs) { LayoutInflater inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService); inflater.Inflate(Resource.Layout.calendar_control, this); LoadDateFormat(attrs); AssignUIElements(); AssignClickHandlers(); UpdateCalendar(); } private voID LoadDateFormat(IAttributeSet attrs) { TypedArray ta = Context.ObtainStyledAttributes(attrs, Resource.Styleable.EstiCalendar); try { // try to load provIDed date format, and fallback to default otherwise dateFormat = ta.GetString(Resource.Styleable.EstiCalendar_date_format); if (dateFormat == null) dateFormat = DATE_FORMAT; } finally { ta.Recycle(); } } private voID AssignUIElements() { // layout is inflated, assign local variables to components header = (linearLayout)FindVIEwByID(Resource.ID.calendar_header); btnPrev = (ImageVIEw)FindVIEwByID(Resource.ID.calendar_prev_button); btnNext = (ImageVIEw)FindVIEwByID(Resource.ID.calendar_next_button); txtDate = (TextVIEw)FindVIEwByID(Resource.ID.calendar_date_display); grID = (GrIDVIEw)FindVIEwByID(Resource.ID.calendar_grID); } private voID AssignClickHandlers() { btnNext.Click += (sender, e) => { currentDate.Add(Calendar.Month, 1); UpdateCalendar(); }; btnPrev.Click += (sender, e) => { currentDate.Add(Calendar.Month, -1); UpdateCalendar(); }; grID.ItemLongClick += (object sender, AdapterVIEw.ItemLongClickEventArgs e) => { if (eventHandler != null) { eventHandler.OnDayLongPress((Date)e.position); } }; } public voID UpdateCalendar() { UpdateCalendar(null); } /** * display dates correctly in grID */ public voID UpdateCalendar(HashSet<Date> events) { List<Date> cells = new List<Date>(); Calendar calendar = (Calendar)currentDate.Clone(); // determine the cell for current month's beginning calendar.Set(Calendar.DayOfMonth, 1); int monthBeginningCell = calendar.Get(Calendar.DayOfWeek) - 1; // move calendar backwards to the beginning of the week calendar.Add(Calendar.DayOfMonth, -monthBeginningCell); // fill cells while (cells.Count < DAYS_COUNT) { cells.Add(calendar.Time); calendar.Add(Calendar.DayOfMonth, 1); } // update grID grID.Adapter = new Calendaradapter(Context, cells, events); // update Title SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); txtDate.Text = sdf.Format(currentDate.Time); // set header color according to current season int month = currentDate.Get(Calendar.Month); int season = monthSeason[month]; int color = rainbow[season]; header.SetBackgroundcolor(Resources.Getcolor(color)); } private class Calendaradapter : BaseAdapter<Date> { // days with events private HashSet<Date> eventDays; private List<Date> days; // for vIEw inflation private LayoutInflater inflater; private Context context; public Calendaradapter(Context context, List<Date> days, HashSet<Date> eventDays) : base() { this.eventDays = eventDays; this.days = days; inflater = LayoutInflater.From(context); this.context = context; } public overrIDe Date this[int position] => days[position]; public overrIDe int Count => days.Count; public overrIDe long GetItemID(int position) { return position; } public overrIDe VIEw GetVIEw(int position, VIEw convertVIEw, VIEwGroup parent) { // day in question var date = GetItem(position) as Date; int day = date.GetDate(); int month = date.Month; int year = date.Year; // today Date today = new Date(); // inflate item if it does not exist yet if (convertVIEw == null) convertVIEw = inflater.Inflate(Resource.Layout.control_calendar_day, parent, false); // if this day has an event, specify event image convertVIEw.SetBackgroundResource(0); if (eventDays != null) { foreach (Date eventDate in eventDays) { if (eventDate.GetDate() == day && eventDate.Month == month && eventDate.Year == year) { // mark this day for event convertVIEw.SetBackgroundResource(Resource.Drawable.reminder); break; } } } // clear styling ((TextVIEw)convertVIEw).SetTypeface(null, TypefaceStyle.normal); ((TextVIEw)convertVIEw).SetTextcolor(color.Black); if (month != today.Month || year != today.Year) { // if this day is outsIDe current month, grey it out ((TextVIEw)convertVIEw).SetTextcolor(context.Resources.Getcolor(Resource.color.greyed_out)); } else if (day == today.GetDate()) { // if it is today, set it to blue/bold ((TextVIEw)convertVIEw).SetTypeface(null, TypefaceStyle.Bold); ((TextVIEw)convertVIEw).SetTextcolor(context.Resources.Getcolor(Resource.color.today)); } // set text ((TextVIEw)convertVIEw).Text = $"{date.GetDate()}"; return convertVIEw; } } public voID SetEventHandler(IEventHandler eventHandler) { this.eventHandler = eventHandler; } public interface IEventHandler { voID OnDayLongPress(Date date); } }}
CalendarFragment.cs包含错误:
using System;using System.Collections.Generic;using AndroID.OS;using AndroID.Runtime;using AndroID.VIEws;using AndroID.Widget;using EstiMOBILE.DroID.Components.EstiCalendar.Component.Layouts;using EstiMOBILE.DroID.Fragments.BaseFragments;using Java.Util;namespace EstiMOBILE.DroID.Fragments.CustomFragments{ public class CalendarFragment : BaseFragment { public overrIDe voID OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); } public static CalendarFragment NewInstance() { var frag1 = new CalendarFragment { Arguments = new Bundle() }; return frag1; } public overrIDe VIEw OnCreateVIEw(LayoutInflater inflater, VIEwGroup container, Bundle savedInstanceState) { var vIEw = inflater.Inflate(Resource.Layout.calendar_fragment_main, container, false); //Error //InitCustomCalendar(vIEw); return vIEw; } public voID InitCustomCalendar(VIEw vIEw) { HashSet<Date> events = new HashSet<Date> { new Date() }; EstiCalendar cv = (EstiCalendar) vIEw.FindVIEwByID(Resource.ID.esti_calendar); cv.UpdateCalendar(events); } }}
您有什么帮助,如何摆脱这个错误?
解决方法:
您不需要其他的构造函数
public EstiCalendar(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer){}
问题是Java和Xamarin之间的名称空间,您应该在XML文件中使用小写字母表示名称空间,使用camelcase表示类名称.更改您的xml文件,例如:
<estimobile.droID.components.esticalendar.component.layouts.EstiCalendar androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:ID="@+ID/esti_calendar" esticalendar:date_format="MMMM yyyy" />
总结 以上是内存溢出为你收集整理的添加自己的LinearLayout期间无法激活JNI手柄-Xamarin Android全部内容,希望文章能够帮你解决添加自己的LinearLayout期间无法激活JNI手柄-Xamarin Android所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)