Android 适配器教程 (六)

简介:

我们的适配器学习已经接近尾声了,虽然这不是一个大问题,但是确实是值得学习的一块知识,回想一下之前五讲的知识,我们已经学到了很多东西了。

              

在之前五讲中,我们已经由浅入深的认识了适配器,从最简单的ListView写起,最后完成了自定义适配器的简单例子,然后又为大家讲解了ViewHolder和settag在自定义适配器中的应用,帮助大家理解了getView方法,还讲解了关于ListView性能方面的优化问题。自定义适配器这一部分是我们这次学习真正的重点,很多问题可以用安卓原生适配器进行解决,但是也有很多问题必须通过自定义适配器才能合适的解决。

 

在第四讲我已经提到过了,关于自定义适配器,我们将有两个例子,一个简单一点,一个稍微难一点,今天我们这个例子,也是最后一个例子是一个比较繁琐的项目,希望大家认真学习,并从中领悟到知识,真正学通安卓适配器。

 

好的,先介绍一下今天要做的例子,大家都知道Listview和GridView,这两个都是安卓开发中常用的控件,今天我们要把他们两个结合在一起,使用listView嵌套GridView,形成一种可以存放多张图片的UI设计,Google+android客户端就是这个样子是不是感到有一点小繁琐,不过没事,我会一步步的按照写代码的思路讲解的。

 

说明一下,我还是会在之前几讲的Demo上继续添加,这次写完我就把源码双手奉上了哦,看过前几篇的读者就比较熟悉了。

 

好的,现在开始动手写吧:

 

项目开始:

 

(1)也还是先在activity_main.xml里添加一个button,一会跳转的时候使用。

(2)然后新建一个类FinalDemo继承自Activity作为我们第四个个例子的Activity@Override我们的onCreate方法。

(3)新建一个xml文件finaldemo.xml作为我们的布局文件,其中也是包含一个文本域和一个ListView

代码如下:

finaldemo.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="这是ListView与GridView嵌套的一个例子" >
    </TextView>

    <ListView
        android:id="@+id/finaldemolistview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

(4)然后需要定义好一个用来显示每一个列内容的xml文件Listitem3.xmlListitem3.xml 包含横向的一个图片还有一个GridviewGridview的横向滚动的实现布局主要是把gridview嵌套在HorizontalScrollView里面GridView的一些属性还要在java代码中实现,一会大家看源码就明白了。

Listitem3.xml

代码如下:

<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/list_iv"
        android:layout_width="150px"
        android:layout_height="150px"
        android:scaleType="fitXY"
        />

    <HorizontalScrollView
        android:id="@+id/app_grid"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@null"
        android:scrollbars="none" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <GridView
                android:id="@+id/gridview"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="@null" >
            </GridView>
        </LinearLayout>
    </HorizontalScrollView>

</LinearLayout></span>


再嵌套一个线性布局是为了在Java代码中控制横向Gridview长度(总长度)的,通过LayoutParams方法。


(5)然后需要定义好一个用来显示横向GridView每一个内容的gridview_item.xml,内容是一个ImageView和一个textview


代码如下:

gridview_item.xml:

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

    <ImageView
        android:id="@+id/Grid_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/Grid_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

(6)然后是写出GridView的适配器这里在第四讲讲已经很详细的说过了,我就不再多费口舌了,有什么问题还请大家再回去看看吧:

新建一个类GridViewAdapter extends BaseAdapter,之后重写方法就Ok了~


以下是该类的完整代码:

package com.example.adapterdemo;

import java.util.List;
import java.util.Map;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import android.widget.ImageView;
import android.widget.TextView;

public class GridViewAdapter extends BaseAdapter {

	private LayoutInflater mInflater;
	private List<Map<String, Object>> Griddata;

	// 构造器,接收数据
	public GridViewAdapter(Context context, List<Map<String, Object>> Griddata) {

		this.mInflater = LayoutInflater.from(context);
		this.Griddata = Griddata;
	}

	@Override
	public int getCount() {

		return Griddata == null ? 0 : Griddata.size();
	}

	@Override
	public Object getItem(int position) {

		return Griddata.get(position);
	}

	@Override
	public long getItemId(int position) {

		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		if (convertView == null) {

			holder = new ViewHolder();

			convertView = mInflater.inflate(R.layout.gridview_item, null);
			holder.Gridimg = (ImageView) convertView.findViewById(R.id.Grid_iv);
			holder.Gridtext = (TextView) convertView.findViewById(R.id.Grid_tv);

			convertView.setTag(holder);

		} else {

			holder = (ViewHolder) convertView.getTag();
		}

		holder.Gridimg.setBackgroundResource((Integer) Griddata.get(position)
				.get("Gridimg"));
		holder.Gridtext
				.setText((String) Griddata.get(position).get("Gridtext"));

		return convertView;
	}

	public final class ViewHolder {
		public ImageView Gridimg;
		public TextView Gridtext;

	}

}

(7)然后是写出LIstView的适配器这里在第四讲讲已经很详细的说过了,我同样也是就不再多费口舌了,有什么问题还请大家再回去看看吧:

新建一个类FinalDemoListAdapter extends BaseAdapter,之后重写方法就Ok了~

其中需要注意的就有 1.构造器部分需要分两部分得到ListView和GridView的数据。


2.原来加载数据的部分,由于我们里面还嵌套了一层ListView,所以除了加载了一张 图片,还需要加载一个GridView,并且把外部获得的给GridView的数据传给下一层。


3.GridView的布局设置,这里我就不多说了,有问题的话谷歌一下就明白了。


另外我这么写思路比较清楚,但是效率就不敢保证了,还希望大家多多指教。


下面给出源码:


package com.example.adapterdemo;

import java.util.List;
import java.util.Map;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;


public class FinalDemoListAdapter extends BaseAdapter {
	
	 //列宽

    private int cWidth = 120;

    //水平间距

    private int hSpacing = 10;


	private LayoutInflater mInflater;
	private List<Map<String, Object>> Listdata;
	private List<Map<String, Object>> Griddata;
	private Context context;

	// 构造器,接收数据
	public FinalDemoListAdapter(Context context,
			List<Map<String, Object>> Listdata,
			List<Map<String, Object>> Griddata) {
		this.context = context;
		this.mInflater = LayoutInflater.from(context);
		this.Listdata = Listdata;
		this.Griddata = Griddata;
	}

	@Override
	public int getCount() {

		return Listdata == null ? 0 : Listdata.size();
	}

	@Override
	public Object getItem(int position) {

		return Listdata.get(position);
	}

	@Override
	public long getItemId(int position) {

		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		if (convertView == null) {

			holder = new ViewHolder();

			convertView = mInflater.inflate(R.layout.listitem3, null);

			holder.Listimg = (ImageView) convertView.findViewById(R.id.list_iv);
			holder.gridview = (GridView) convertView
					.findViewById(R.id.gridview);

			convertView.setTag(holder);

		} else {

			holder = (ViewHolder) convertView.getTag();
		}

		// 加载数据
		holder.Listimg.setBackgroundResource((Integer) Listdata.get(position)
				.get("Listimg"));

		// 加载Gridview
		GridViewAdapter ga = new GridViewAdapter(context, Griddata);

		int i = ga.getCount();

		LayoutParams params = new LayoutParams(i * (115 + 10),

		LayoutParams.WRAP_CONTENT);

		holder.gridview.setLayoutParams(params);

		holder.gridview.setColumnWidth(cWidth);

		holder.gridview.setHorizontalSpacing(hSpacing);

		holder.gridview.setStretchMode(GridView.NO_STRETCH);

		holder.gridview.setNumColumns(i);

		holder.gridview.setAdapter(ga);

		return convertView;
	}

	public final class ViewHolder {
		public ImageView Listimg;
		public GridView gridview;

	}

}

(8)之后我们再回到FinalDem之前那样增加适配器,添加数据就好了:


我从网上下了点头像。。。后面的安卓机器人图片是示例。


下面是源码:

package com.example.adapterdemo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class FinalDemo extends Activity {
	private ListView lv;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.finaldemo);
		lv = (ListView) findViewById(R.id.finaldemolistview);
		FinalDemoListAdapter myadapter = new FinalDemoListAdapter(this,
				getListData(), getGridData());
		lv.setAdapter(myadapter);
	}

	private List<Map<String, Object>> getListData() {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head1);
		
		list.add(map);

		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head2);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head4);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head5);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head6);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head7);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head8);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head9);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head10);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head11);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head12);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head13);
		list.add(map);
		
		return list;
		
	}

	private List<Map<String, Object>> getGridData() {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 1");
		
		list.add(map);

		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 2");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 3");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 4");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 5");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 6");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 7");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 8");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 9");
		
		list.add(map);
		return list;
	}
}


到此为止就搞定了!,让我们再看一下实现效果




为了能看出效果,我把横向的Gridview拉动了一下,所以是对不齐的,这里我横向的部分设置的底色为透明,如果在加一张背景图片的话,相信效果会不错的,这只是一个Demo,在调整一下间距和尺寸,我想效果会好很多,呵呵~


这样我们的教程就算是彻底结束了,希望大家能从中学到些东西就好了,这样我的Demo程序也一并写完了,源码地址我会附在文章的最后~

差点忘了我还没给大家activity_main.xml和MainActivity的源码,这里也再贴一下吧:


MainActivity:

package com.example.adapterdemo;



import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
	private Button bt_1;
	private Button bt_2;
	private Button bt_3;
	private Button bt_4;
	private Button bt_5;
	private Button bt_6;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt_1=(Button)findViewById(R.id.button1);
        bt_2=(Button)findViewById(R.id.button2);
        bt_3=(Button)findViewById(R.id.button3);
        bt_4=(Button)findViewById(R.id.button4);
        bt_5=(Button)findViewById(R.id.button5);
        bt_6=(Button)findViewById(R.id.button6);
        
        bt_1.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				Intent dataIntent = new Intent(MainActivity.this,ArrayAdapterDemo.class);
				 startActivity(dataIntent);
			}
		});
        
        bt_2.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				Intent dataIntent = new Intent(MainActivity.this,SimpleCursorAdapterDemo.class);
				 startActivity(dataIntent);
			}
		});
        
        bt_3.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				Intent dataIntent = new Intent(MainActivity.this,SimpleAdapterDemo.class);
				 startActivity(dataIntent);
			}
		});
        
        bt_4.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				Intent dataIntent = new Intent(MainActivity.this,MyAdapterDemo.class);
				 startActivity(dataIntent);
			}
		});
        
        bt_5.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				Intent dataIntent = new Intent(MainActivity.this,FinalDemo.class);
				 startActivity(dataIntent);
			}
		});
        
        bt_6.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				aboutWarn();
			}
		});
    }

    private void aboutWarn(){
		AlertDialog.Builder builder = new Builder(this); 
		builder.setMessage("这是关于学习适配器的一个例子\n作者MingChao Sun\n相关教程请访问:\nhttp://blog.csdn.net/sunmc1204953974");
		builder.setTitle("关于");
		builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				
				dialog.dismiss();
			}
		});
		builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				
				dialog.dismiss();
			}
		});
		builder.create().show();
	}

   
}


activity_main.xml:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

     <Button
         android:id="@+id/button2"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentLeft="true"
         android:layout_below="@+id/button1"
         android:layout_marginTop="27dp"
         android:text="SimpleCursorAdapterDemo" />

     <Button
         android:id="@+id/button5"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentLeft="true"
         android:layout_below="@+id/button4"
         android:layout_marginTop="26dp"
         android:text="ListView与GridView嵌套的Demo" />

     <Button
         android:id="@+id/button6"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true"
         android:text="关于" />

     <Button
         android:id="@+id/button1"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignLeft="@+id/button2"
         android:layout_below="@+id/button6"
         android:layout_marginTop="20dp"
         android:text="ArrayAdapterDemo" />

     <Button
         android:id="@+id/button3"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_below="@+id/button2"
         android:layout_marginTop="18dp"
         android:text="SimpleAdapterDemo" />

     <Button
         android:id="@+id/button4"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentLeft="true"
         android:layout_below="@+id/button3"
         android:layout_marginTop="25dp"
         android:text="MyAdapterDemo" />
     
</RelativeLayout>


好了,这就算是彻底结束了,希望大家有所所收获!


我也是学生,水平有限,还请大家多多指教!


另外请大家尊重原创,转载请付上我文章的地址哦~谢谢~


源码的地址:

(一个实例彻底学会适配器)AdapterDemo.zip:

http://download.csdn.net/detail/sunmc1204953974/7689411


目录
相关文章
|
8月前
|
网络协议 Android开发 数据安全/隐私保护
Android手机上使用Socks5全局代理-教程+软件
Android手机上使用Socks5全局代理-教程+软件
5493 2
|
8月前
|
缓存 网络协议 安全
49. 【Android教程】HTTP 使用详解
49. 【Android教程】HTTP 使用详解
130 1
|
3月前
|
Android开发 数据安全/隐私保护 虚拟化
安卓手机远程连接登录Windows服务器教程
安卓手机远程连接登录Windows服务器教程
517 4
|
3月前
|
Android开发
布谷语音软件开发:android端语音软件搭建开发教程
语音软件搭建android端语音软件开发教程!
|
8月前
|
XML 存储 JSON
51. 【Android教程】JSON 数据解析
51. 【Android教程】JSON 数据解析
192 2
|
8月前
|
存储 API 文件存储
47. 【Android教程】SharedPreferences 存储
47. 【Android教程】SharedPreferences 存储
87 2
|
8月前
|
存储 安全 大数据
46. 【Android教程】文件存储
46. 【Android教程】文件存储
84 3
|
8月前
|
存储 编解码 Android开发
58. 【Android教程】音频录制:MediaRecord
58. 【Android教程】音频录制:MediaRecord
84 2
|
8月前
|
设计模式 Android开发
44. 【Android教程】广播接收器:Broadcast Receiver
44. 【Android教程】广播接收器:Broadcast Receiver
197 2
|
8月前
|
安全 数据库 Android开发
45. 【Android教程】内容提供者 - Content Provider
45. 【Android教程】内容提供者 - Content Provider
106 2

热门文章

最新文章

  • 1
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
  • 2
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 4
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 5
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 6
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 7
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
  • 8
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 9
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 10
    Android 13 SystemUI 启动流程
  • 1
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    23
  • 2
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    21
  • 3
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
    52
  • 4
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    35
  • 5
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
    70
  • 6
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    111
  • 7
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
    29
  • 8
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
    263
  • 9
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
    75
  • 10
    【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    36