如何在Kotlin Android中从JSON获取数据

时间:2018-08-20 11:51:10

标签: android json parsing kotlin

我想获取一些json数据,在图像中看到绿色箭头:

enter image description here

问题是Android Studio不允许我获取所需的数据。它会一直停到(我认为)之前。在我的适配器类中,检查:

holder?.view?.textWeather?.text = weatherFor.weather.toString()

它还在模拟器中向我显示红色箭头,这是什么?

下面是我主要的Activity的json方法,其中包含我要为其获取数据的类以及关联的Adapter类。

主要活动

fun fetchJson() {
     val url="https://api.openweathermap.org/data/2.5/forecast?q=Prague,CZ&appid=4cf7f6610d941a1ca7583f50e7e41ba3"
     val request=Request.Builder().url(url).build()
     val client= OkHttpClient()
     client.newCall(request).enqueue(object :Callback {

         override fun onResponse(call: Call?, response: Response?) {
             val body=response?.body()?.string()
             println(body)

             val gson=GsonBuilder().create()

             val forecastfeed=gson.fromJson(body,ForecastFeed::class.java)

             runOnUiThread{
                 recyclerView_main.adapter=MainAdapter(forecastfeed)
             }
         }

         override fun onFailure(call: Call?, e: IOException?) {
             println("Failed to execute request")
         }
     })
}

class ForecastFeed(val list:List<ForecastWeatherList>) { }

class ForecastWeatherList(val weather:List<WeatherData>) { }

class WeatherData(val main:String,val icon:String) { }

适配器

class MainAdapter(val forecastfeed: ForecastFeed): RecyclerView.Adapter<CustomViewHolder>() {

    val forecastWeather = listOf<String>("First","Second")

    override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
        val weatherFor = forecastfeed.list.get(position)
        holder?.view?.textWeather?.text = weatherFor.weather.toString()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder{
        //how do we even create a view
        val layoutInflater =LayoutInflater.from(parent?.context)
        val cellForRow=layoutInflater.inflate(R.layout.weather_row,parent,false)
        return CustomViewHolder(cellForRow)
    }    

    override fun getItemCount(): Int {
        return forecastfeed.list.count()
    }
}

class CustomViewHolder(val view: View):RecyclerView.ViewHolder(view) { }

2 个答案:

答案 0 :(得分:2)

您可以手动设置数据格式

holder?.view?.textWeather?.text = "weather ${weatherFor.weather.map{it.main}.joinToString(", ")}"

或使用data classes

答案 1 :(得分:0)

您需要覆盖class WeatherData(val main:String,val icon:String) { override fun toString(): String { return "$main $icon" } } 才能掌握显示的内容。

RecyclerView

此外,您应该将ViewHolderclass TrayTooltip { public static List<String> ScanToolbarButtons() { List<string> tooltips = new List<string>(); var handle = GetSystemTrayHandle(); if (handle == IntPtr.Zero) return null; var count = SendMessage(handle, TB_BUTTONCOUNT, IntPtr.Zero, IntPtr.Zero).ToInt32(); if (count == 0) return null; int pid; GetWindowThreadProcessId(handle, out pid); var hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid); if (hProcess == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error()); var size = (IntPtr)Marshal.SizeOf<TBBUTTONINFOW>(); var buffer = VirtualAllocEx(hProcess, IntPtr.Zero, size, MEM_COMMIT, PAGE_READWRITE); if (buffer == IntPtr.Zero) { CloseHandle(hProcess); throw new Win32Exception(Marshal.GetLastWin32Error()); } for (int i = 0; i < count; i++) { var btn = new TBBUTTONINFOW(); btn.cbSize = size.ToInt32(); btn.dwMask = TBIF_BYINDEX | TBIF_COMMAND; IntPtr written; if (WriteProcessMemory(hProcess, buffer, ref btn, size, out written)) { // we want the identifier var res = SendMessage(handle, TB_GETBUTTONINFOW, (IntPtr)i, buffer); if (res.ToInt32() >= 0) { IntPtr read; if (ReadProcessMemory(hProcess, buffer, ref btn, size, out read)) { // now get display text using the identifier // first pass we ask for size var textSize = SendMessage(handle, TB_GETBUTTONTEXTW, (IntPtr)btn.idCommand, IntPtr.Zero); if (textSize.ToInt32() != -1) { // we need to allocate for the terminating zero and unicode var utextSize = (IntPtr)((1 + textSize.ToInt32()) * 2); var textBuffer = VirtualAllocEx(hProcess, IntPtr.Zero, utextSize, MEM_COMMIT, PAGE_READWRITE); if (textBuffer != IntPtr.Zero) { res = SendMessage(handle, TB_GETBUTTONTEXTW, (IntPtr)btn.idCommand, textBuffer); if (res == textSize) { var localBuffer = Marshal.AllocHGlobal(utextSize.ToInt32()); if (ReadProcessMemory(hProcess, textBuffer, localBuffer, utextSize, out read)) { var text = Marshal.PtrToStringUni(localBuffer); tooltips.Add(text); Marshal.FreeHGlobal(localBuffer); } } VirtualFreeEx(hProcess, textBuffer, size, MEM_RELEASE); } } } } } } VirtualFreeEx(hProcess, buffer, size, MEM_RELEASE); CloseHandle(hProcess); return tooltips; } private static IntPtr GetSystemTrayHandle() { var hwnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "Shell_TrayWnd", null); hwnd = FindWindowEx(hwnd, IntPtr.Zero, "TrayNotifyWnd", null); hwnd = FindWindowEx(hwnd, IntPtr.Zero, "SysPager", null); return FindWindowEx(hwnd, IntPtr.Zero, "ToolbarWindow32", null); } [DllImport("kernel32", SetLastError = true)] private static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); [DllImport("kernel32", SetLastError = true)] private static extern bool CloseHandle(IntPtr hObject); [DllImport("kernel32", SetLastError = true)] private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, ref TBBUTTONINFOW lpBuffer, IntPtr nSize, out IntPtr lpNumberOfBytesWritten); [DllImport("kernel32", SetLastError = true)] private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, ref TBBUTTONINFOW lpBuffer, IntPtr nSize, out IntPtr lpNumberOfBytesRead); [DllImport("kernel32", SetLastError = true)] private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, IntPtr nSize, out IntPtr lpNumberOfBytesRead); [DllImport("user32", SetLastError = true)] private static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId); [DllImport("kernel32", SetLastError = true)] private static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, IntPtr dwSize, int flAllocationType, int flProtect); [DllImport("kernel32", SetLastError = true)] private static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, IntPtr dwSize, int dwFreeType); [DllImport("user32")] private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32", SetLastError = true)] private static extern IntPtr FindWindowEx(IntPtr hWndParent, IntPtr hWndChildAfter, string lpClassName, string lpWindowName); private const int TBIF_BYINDEX = unchecked((int)0x80000000); // this specifies that the wparam in Get/SetButtonInfo is an index, not id private const int TBIF_COMMAND = 0x20; private const int MEM_COMMIT = 0x1000; private const int MEM_RELEASE = 0x8000; private const int PAGE_READWRITE = 0x4; private const int TB_GETBUTTONINFOW = 1087; private const int TB_GETBUTTONTEXTW = 1099; private const int TB_BUTTONCOUNT = 1048; private static bool IsWindowsVistaOrAbove() => Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6; private static int PROCESS_ALL_ACCESS => IsWindowsVistaOrAbove() ? 0x001FFFFF : 0x001F0FFF; [StructLayout(LayoutKind.Sequential)] private struct TBBUTTONINFOW { public int cbSize; public int dwMask; public int idCommand; public int iImage; public byte fsState; public byte fsStyle; public short cx; public IntPtr lParam; public IntPtr pszText; public int cchText; } } 一起使用,以一对一地处理属性并启用更复杂的布局。如果需要的话。