精华内容
下载资源
问答
  • 使用Ti.Network.createHTTPClient...使用commonJS模块化规范JS代码 自定义tableview行数据 使用webview展示web内容 跨平台设计 转载于:https://www.cnblogs.com/xiaozhanga4/archive/2012/10/30/2745617.html...

    使用Ti.Network.createHTTPClient访问远程数据

    使用commonJS模块化规范JS代码

    自定义tableview行数据

    使用webview展示web内容

    跨平台设计

     

    ti

    转载于:https://www.cnblogs.com/xiaozhanga4/archive/2012/10/30/2745617.html

    展开全文
  • 而个性化新闻APP平台,新闻的获取速度虽然没国内知名的新闻资讯平台快,当是它的特点主要在个性化这个点上,用户可以根据自己的兴趣爱好设置自己喜欢观看的新闻。灵活自由。 本APP的特点就是轻捷方便,个性化设置,...
  • h5+app页面间的传值

    千次阅读 2018-12-09 22:34:36
    App开发中,经常会遇到页面间传值的需求,比如从新闻列表页进入详情页,需要将新闻id传递过去; Html5Plus规范设计了evalJS方法来解决该问题; 但evalJS方法仅接收字符串参数,涉及多个参数时,需要开发人员手动拼...

    在App开发中,经常会遇到页面间传值的需求,比如从新闻列表页进入详情页,需要将新闻id传递过去; Html5Plus规范设计了evalJS方法来解决该问题; 但evalJS方法仅接收字符串参数,涉及多个参数时,需要开发人员手动拼字符串; 为简化开发,mui框架在evalJS方法的基础上,封装了自定义事件,通过自定义事件,用户可以轻松实现多webview间数据传递。因为是多webview之间传值,故无法在手机浏览器、微信中使用;
    添加自定义事件监听操作和标准js事件监听类似,可直接通过window对象添加,如下:

    window.addEventListener(‘customEvent’,function(event){
    //通过event.detail可获得传递过来的参数内容

    });
    通过mui.fire()方法可触发目标窗口的自定义事件:
    mui.fire(detailPage,‘newsId’,{})

    //初始化预加载详情页面
    mui.init({
    preloadPages:[{
    id:‘detail.html’,
    url:‘detail.html’
    }
    ]
    });
    用了这个后可以这样打开页面
    mui.openWindow({
    id:‘detail.html’
    });

    	var detailPage = null;
    	//添加列表项的点击事件
    	mui('.mui-content').on('tap', '.mui-slider', function(e) {
    		var id = this.getAttribute('id');
    		//获得详情页面
    		if(!detailPage) {
    			detailPage = plus.webview.getWebviewById('detail.html');
    		}
    		//触发详情页面的newsId事件
    		mui.fire(detailPage, 'newsId', {
    			id: id
    		});
    		//打开详情页面          
    		mui.openWindow({
    			id: 'detail2.html'
    
    		});
    	});
    

    详情页面代码如下:
    //添加newId自定义事件监听

    window.addEventListener('newsId',function(event){
      //获得事件参数
      var id = event.detail.id;
    });
    
    展开全文
  • 移动开发规范

    2017-03-07 14:38:00
    移动端常用的的字号有哪些呢? 导航主标题字号:40-42px ...像新闻类的APP或文字阅读类的APP更注重文本的阅读便捷性,正文字号36px,会选择性的加粗。 而列表形式、工具化的APP普遍是正文32px,不加粗。副文案26p...

    移动端常用的的字号有哪些呢?

     导航主标题字号:40-42px

     我一般设计就用40px,偏小的40px字号,显得精致些。

    大的正文字号32px, 副文是26px,小字20px 在内文的使用中,根据不同类型的App会有所区别,

    像新闻类的APP或文字阅读类的APP更注重文本的阅读便捷性,正文字号36px,会选择性的加粗。

    而列表形式、工具化的APP普遍是正文32px,不加粗。副文案26px,小字20px

     36px的字号还经常运用在页面的大按钮中。为了拉开按钮的层次,同时加强按钮引导性,选用了稍大号的字体

     大家注意了,在选用字体大小的时候一定要选择偶数的字号,因为在开发界面的时候,字号大小换算是要除以二的。

    这个详细缘由大家可以网上查询,我就不在这一一的介绍了。

     网页端 
    常用的字号有哪些呢? 
    网页中文字字号一般都是宋体12px或14px(无状态),大号字体用微软雅黑或黑体。大号字体是18px、20px、26px、30px,
    一般使用双数字号,单数的字体在显示的时候会有毛边。
    字体颜色又有哪些常用的颜色呢? 
     
    在界面中的文字分为三个层级,主文、副文、提示文案等。 在白色的背景下,字体的颜色层次其实就是黑、深灰、灰色。 
    常用的色值是#333333;#666666;#999999
    在界面中还经常会用到背景色#eeeeee。 
    分割线则采用#e5e5e5或#cccccc的颜色值,一个深一些,一个浅一些。这个会更具不同的软件风格采用不同的深浅,由设计自己把控

     

     

     

     

     

     

    转载于:https://www.cnblogs.com/infernofranz/p/6514654.html

    展开全文
  • 自定义GridLayout控件,可以在新闻咨询类APP中的管理页面使用到,也可以应用在类别管理中,总之,可以帮助我们设计更加规范和炫酷的手机页面。新闻app是最常见的应用之一,而频道管理又是其必不可少的功能,该...

    新闻频道管理的炫酷实现

    gridlayout.jpg

    自定义GridLayout控件,可以在新闻咨询类APP中的管理页面使用到,也可以应用在类别管理中,总之,可以帮助我们设计更加规范和炫酷的手机页面。

    新闻类app是最常见的应用之一,而频道管理又是其必不可少的功能,该自定义控件不仅可以带我们实现炫酷的频道管理功能,还可以让我们学习如何使用Android拖拽框架实现我们想要的多种功能,以及让我们对自定义控件会有更多的理解。

    知识点

    1. GridLayout的使用

      • 从Google官方文档学习GridLayout的功能以及用法
      • 使用GridLayout实现子控件排列显示
    2. View的拖拽功能实现

      • 通过查看Google文档,学会调用view的拖拽方法
      • 拖拽事件的处理
      • 使用View的拖拽框架实现实现频道切换位置效果
    3. 自定义GridLayout控件

      自定义GridLayout控件,实现拖拽功能,继而实现频道管理操作

    4. Rect类的使用

      使用Rect类确定被触摸到的子控件

    新闻频道管理的多种实现

    实现类似于网易新闻频道管理有几种方式

    实现方案1:使用两个GridView实现,这是比较早的一种解决方案,比较复杂,具体可以参考 Android 高仿 频道管理—-网易、今日头条、腾讯视频

    实现方案2:使用两个RecyclerView或ListView实现,这种实现方式好于于方案1

    实现方案3:使用一个RecyclerView实现,这是我目前见过的比较好的方式,貌似比网易新闻等客户端的要流畅,具体可以参考:高仿网易新闻栏目动画效果使用ItemTouchHelper高效地实现 今日头条 、网易新闻 的频道排序、移动

    实现方案4:使用两个GridLayout实现,也就是本文要介绍的方式

    拖拽

    长按item开始拖拽

    private View.OnLongClickListener longClickListener = new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                //长按时,开始拖拽操作,显示出阴影
                //被拖拽的视图其实就是v参数
                dragedView = v;
                v.startDrag(null, new View.DragShadowBuilder(v), null, 0);
                v.setEnabled(false);
                // v.startDragAndDrop(null, new View.DragShadowBuilder(v), null, 0);
                return false;
            }
        };

    拖拽方法参数说明

    • startDragAndDrop() api24
    • startDrag(ClipData data, DragShadowBuilder shadowBuilder, Object myLocalState, int flag)

    参数1:ClipData data 拖拽过程中可以transferred的数据,可以为空

    参数2:DragShadowBuilder shadowBuilder,拖拽阴影效果创建者

    参数3:Object myLocalState,拖拽状态

    参数4:int flag,可以控制拖拽操作的flag,未定义,传0即可

    拖拽监听

    private View.OnDragListener dragListener =  new View.OnDragListener() {
            /**
             * ACTION_DRAG_STARTED:当拖拽操作执行时,就会执行一次
             * DragEvent.ACTION_DRAG_ENDED:当拖拽事件结束,手指抬起时,就是执行一次
             * DragEvent.ACTION_DRAG_ENTERED:当手指进入设置了拖拽监听的控件范围内的瞬间执行一次
             * DragEvent.ACTION_DRAG_EXITED:当手指离开设置了拖拽监听的控件范围内的瞬间执行一次
             * DragEvent.ACTION_DRAG_LOCATION:当手指在设置了拖拽监听的控件范围内,移动时,实时会执行,执行N次
             * DragEvent.ACTION_DROP:当手指在设置了拖拽监听的控件范围内松开时,执行一次
             *
             *
             * @param v 当前监听拖拽事件的view(其实就是mGridLayout)
             * @param event 拖拽事件
             * @return
             */
            @Override
            public boolean onDrag(View v, DragEvent event) {
                String dragEventAction = getDragEventAction(event);
                System.out.println(dragEventAction);
                //            Rect rect = new Rect();
                //            rect.contains()
                switch (event.getAction()) {
                    //当拖拽事件开始时,创建出与子控件对应的矩形数组
                    case DragEvent.ACTION_DRAG_STARTED:
                        initRects();
                        break;
                    case DragEvent.ACTION_DRAG_LOCATION:
                        //手指移动时,实时判断触摸是否进入了某一个子控件
                        int touchIndex = getTouchIndex(event);
                        //说明触摸点进入了某一个子控件,判断被拖拽的视图与进入的子控件对象不是同一个的时候才进行删除添加操作
    
                        if (touchIndex > -1&&dragedView != null&&dragedView != mGridLayout.getChildAt(touchIndex)) {
                            mGridLayout.removeView(dragedView);
                            mGridLayout.addView(dragedView,touchIndex);
                        }
                        break;
                    case DragEvent.ACTION_DRAG_ENDED:
                        //拖拽事件结束后,让被拖拽的view设置为可用,否则背景变红,并且长按事件会失效
                        if (dragedView != null) {
                            dragedView.setEnabled(true);
                        }
                        break;
                }
    
                return true;
            }
        };

    DragEvent

    拖拽事件 说明
    ACTION_DRAG_STARTED 当拖拽操作执行时,就会执行一次
    DragEvent.ACTION_DRAG_ENDED 当拖拽事件结束,手指抬起时,就是执行一次
    DragEvent.ACTION_DRAG_ENTERED 当手指进入设置了拖拽监听的控件范围内的瞬间执行一次
    DragEvent.ACTION_DRAG_EXITED 当手指离开设置了拖拽监听的控件范围内的瞬间执行一次
    DragEvent.ACTION_DRAG_LOCATION 当手指在设置了拖拽监听的控件范围内,移动时,实时会执行,执行N次
    DragEvent.ACTION_DROP 当手指在设置了拖拽监听的控件范围内松开时,执行一次

    当拖拽事件开始时,创建出与子控件对应的矩形数组

    private Rect[] mRects;
    
        private void initRects() {
            mRects = new Rect[mGridLayout.getChildCount()];
            for (int i = 0; i < mGridLayout.getChildCount(); i++) {
                View childView = mGridLayout.getChildAt(i);
                //创建与每个子控件对应矩形对象
                Rect rect = new Rect(childView.getLeft(), childView.getTop(), childView.getRight(), childView.getBottom());
                mRects[i] = rect;
            }
        }

    手指移动时,实时判断触摸是否进入了某一个子控件

    private int getTouchIndex(DragEvent event) {
            //遍历所有的数组,如果包含了当前的触摸点返回索引即可
            for (int i = 0; i < mRects.length; i++) {
                Rect rect = mRects[i];
                if (rect.contains((int)event.getX(), (int)event.getY())) {
                    return i;
                }
            }
            return -1;
        }

    是否允许拖拽

    public void setAllowDrag(boolean allowDrag) {
            this.allowdrag = allowDrag;
            if (this.allowdrag) {
                this.setOnDragListener(odl);
            } else {
                this.setOnDragListener(null);
            }
    
        }

    设置列数和动画

    //初始化方法
    private void init() {
        // android:columnCount="4"
        // android:animateLayoutChanges="true"
        this.setColumnCount(columnCount);
        this.setLayoutTransition(new LayoutTransition());
    }

    DragGridlayout

    public class DragGridlayout extends GridLayout{
    
        private  static final int columnCount = 4;//列数
        private boolean isAllowDrag;//记录当前控件是否可以进行拖拽操作
    
        public DragGridlayout(Context context) {
            this(context,null);
        }
    
        public DragGridlayout(Context context, AttributeSet attrs) {
            this(context, attrs,0);
        }
    
        public DragGridlayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
    /*  static SparseArray<String> dragEventType = new SparseArray<>();
        static{
            dragEventType.put(DragEvent.ACTION_DRAG_STARTED, "STARTED");
            dragEventType.put(DragEvent.ACTION_DRAG_ENDED, "ENDED");
            dragEventType.put(DragEvent.ACTION_DRAG_ENTERED, "ENTERED");
            dragEventType.put(DragEvent.ACTION_DRAG_EXITED, "EXITED");
            dragEventType.put(DragEvent.ACTION_DRAG_LOCATION, "LOCATION");
            dragEventType.put(DragEvent.ACTION_DROP, "DROP");
        }
    
        public static String getDragEventAction(DragEvent de){
            return dragEventType.get(de.getAction());
        }*/
    
        //初始化方法
        private void init() {
            //  android:columnCount="4"
            //  android:animateLayoutChanges="true"
            this.setColumnCount(columnCount);
            this.setLayoutTransition(new LayoutTransition());
        }
    
        public void setItems(List<String> items) {
            for (String item : items) {
                addItem(item);
            }
        }
    
        public void addItem(String content, int index) {
            TextView tv = newItemView();
            tv.setText(content);
            addView(tv,index);
        }
    
        public void addItem(String content) {
            TextView tv = newItemView();
            tv.setText(content);
            addView(tv);
        }
    
        private TextView newItemView() {
            TextView tv = new TextView(getContext());
            int margin = dip2px(5);
            tv.setBackgroundResource(R.drawable.selector_tv_bg);
            GridLayout.LayoutParams layoutParams = new GridLayout.LayoutParams();
            layoutParams.width = getResources().getDisplayMetrics().widthPixels/4 - 2*margin;//宽为屏幕宽的4分之一
            layoutParams.height = dip2px(25);
            layoutParams.setMargins(margin,margin,margin,margin);
            tv.setGravity(Gravity.CENTER);
            tv.setLayoutParams(layoutParams);
    
            if (isAllowDrag) {
                //给条目设置长按点击事件
                tv.setOnLongClickListener(mLongClickListener);
            } else {
                tv.setOnLongClickListener(null);
            }
    
            //设置条目的点击事件
            tv.setOnClickListener(onClickListener);
            return tv;
        }
    
        /** dip转换px */
        public int dip2px(int dip) {
            final float scale = getResources().getDisplayMetrics().density;
            return (int) (dip * scale + 0.5f);
        }
    
        private View dragedView;//被拖拽的视图
    
        private View.OnLongClickListener mLongClickListener = new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                //长按时,开始拖拽操作,显示出阴影
                //被拖拽的视图其实就是v参数
                dragedView = v;
                v.startDrag(null, new View.DragShadowBuilder(v), null, 0);
                v.setEnabled(false);
                //v.startDragAndDrop(null, new View.DragShadowBuilder(v), null, 0); // api24
                return true;
            }
        };
    
        private OnClickListener onClickListener = new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(onDragItemClickListener != null){
                    onDragItemClickListener.onDragItemClick((TextView) v);
                }
            }
        };
    
    
        public void setAllowDrag(boolean isAllowDrag) {
            this.isAllowDrag = isAllowDrag;
            if (this.isAllowDrag) {
                this.setOnDragListener(mDragListener);
            } else {
                this.setOnDragListener(null);
            }
        }
    
        private View.OnDragListener mDragListener =  new View.OnDragListener() {
            /**
             * ACTION_DRAG_STARTED:当拖拽操作执行时,就会执行一次
             * DragEvent.ACTION_DRAG_ENDED:当拖拽事件结束,手指抬起时,就是执行一次
             * DragEvent.ACTION_DRAG_ENTERED:当手指进入设置了拖拽监听的控件范围内的瞬间执行一次
             * DragEvent.ACTION_DRAG_EXITED:当手指离开设置了拖拽监听的控件范围内的瞬间执行一次
             * DragEvent.ACTION_DRAG_LOCATION:当手指在设置了拖拽监听的控件范围内,移动时,实时会执行,执行N次
             * DragEvent.ACTION_DROP:当手指在设置了拖拽监听的控件范围内松开时,执行一次
             *
             * @param v 当前监听拖拽事件的view(其实就是mGridLayout)
             * @param event 拖拽事件
             * @return
             */
            @Override
            public boolean onDrag(View v, DragEvent event) {
                switch (event.getAction()) {
                    //当拖拽事件开始时,创建出与子控件对应的矩形数组
                    case DragEvent.ACTION_DRAG_STARTED:
                        initRects();
                        break;
                    case DragEvent.ACTION_DRAG_LOCATION:
                        //手指移动时,实时判断触摸是否进入了某一个子控件
                        int touchIndex = getTouchIndex(event);
                        //说明触摸点进入了某一个子控件,判断被拖拽的视图与进入的子控件对象不是同一个的时候才进行删除添加操作
    
                        if (touchIndex > -1 && dragedView != null && dragedView != DragGridlayout.this.getChildAt(touchIndex)) {
                            DragGridlayout.this.removeView(dragedView);
                            DragGridlayout.this.addView(dragedView,touchIndex);
                        }
                        break;
                    case DragEvent.ACTION_DRAG_ENDED:
                        //拖拽事件结束后,让被拖拽的view设置为可用,否则背景变红,并且长按事件会失效
                        if (dragedView != null) {
                            dragedView.setEnabled(true);
                        }
                        break;
                }
    
                return true;
            }
        };
    
        //手指移动时,实时判断触摸是否进入了某一个子控件
        private int getTouchIndex(DragEvent event) {
            //遍历所有的数组,如果包含了当前的触摸点返回索引即可
            for (int i = 0; i < mRects.length; i++) {
                Rect rect = mRects[i];
                if (rect.contains((int)event.getX(), (int)event.getY())) {
                    return i;
                }
            }
            return -1;
        }
    
    
        //当拖拽事件开始时,创建出与子控件对应的矩形数组
        private Rect[] mRects;
    
        private void initRects() {
            mRects = new Rect[this.getChildCount()];
            for (int i = 0; i < this.getChildCount(); i++) {
                View childView = this.getChildAt(i);
                //创建与每个子控件对应矩形对象
                Rect rect = new Rect(childView.getLeft(), childView.getTop(), childView.getRight(), childView.getBottom());
                mRects[i] = rect;
            }
        }
    
        private OnDragItemClickListener onDragItemClickListener;
    
        public interface OnDragItemClickListener{
            public void onDragItemClick(TextView tv);
        }
    
        public void setOnDragItemClickListener(OnDragItemClickListener onDragItemClickListener) {
            this.onDragItemClickListener = onDragItemClickListener;
        }
    }

    MainActivity

    布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v4.widget.NestedScrollView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
    
        <LinearLayout
            android:id="@+id/activity_main"
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <Button
                android:layout_width="match_parent"
                android:layout_height="36dp"
                android:gravity="center_vertical"
                android:onClick="addItem"
                android:text="添加条目"
                android:textColor="?android:attr/textColorPrimary"/>
    
            <com.github.draggridlayout.DragGridlayout
                android:id="@+id/selectedChannel"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="16dp"
                android:layout_marginTop="16dp"/>
    
    
            <TextView
                android:id="@+id/textView"
                android:layout_width="match_parent"
                android:layout_height="36dp"
                android:background="?attr/colorButtonNormal"
                android:gravity="center_vertical"
                android:padding="5dp"
                android:text="点击选择频道"
                android:textColor="?android:attr/textColorPrimary"/>
    
            <com.github.draggridlayout.DragGridlayout
                android:id="@+id/unSelectedChannel"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"/>
    
        </LinearLayout>
    
    </android.support.v4.widget.NestedScrollView>

    代码实现

    public class MainActivity extends AppCompatActivity {
    
        private DragGridlayout mSelectedChannel;
        private DragGridlayout mUnSelectedChannel;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            initViews();
            initData();
            initEvent();
        }
    
        private void initViews() {
            setContentView(R.layout.activity_main);
            mSelectedChannel = (DragGridlayout) findViewById(R.id.selectedChannel);
            mUnSelectedChannel = (DragGridlayout) findViewById(R.id.unSelectedChannel);
            mSelectedChannel.setAllowDrag(true);
            mUnSelectedChannel.setAllowDrag(true);
        }
    
        private void initData() {
            List<String> selectedChannel = new ArrayList<>();
            selectedChannel.add("头条");
            ...
            mSelectedChannel.setItems(selectedChannel);
    
            List<String> unSelectedChannel = new ArrayList<>();
            unSelectedChannel.add("NBA");
            ...
            mUnSelectedChannel.setItems(unSelectedChannel);
        }
    
        public void initEvent(){
            //设置条目点击监听
            mSelectedChannel.setOnDragItemClickListener(new DragGridlayout.OnDragItemClickListener() {
                @Override
                public void onDragItemClick(TextView tv) {
                    //移除点击的条目,把条目添加到下面的Gridlayout
                    mSelectedChannel.removeView(tv);//移除是需要时间,不能直接添加
                    mUnSelectedChannel.addItem(tv.getText().toString(),0);
                }
            });
    
            mUnSelectedChannel.setOnDragItemClickListener(new DragGridlayout.OnDragItemClickListener() {
                @Override
                public void onDragItemClick(TextView tv) {
                    //移除点击的条目,把条目添加到上面的Gridlayout
                    mUnSelectedChannel.removeView(tv);//移除是需要时间,不能直接添加
                    mSelectedChannel.addItem(tv.getText().toString());
                }
            });
        }
    
        private int index = 0;
    
        public void addItem(View view) {
            mSelectedChannel.addItem("频道" + index++,0);
        }
    
    }

    源代码

    https://github.com/JackChan1999/DragGridLayout

    展开全文
  • 不管是文件(Java、xml、资源文件)命名,还是布局设计尽量简单简洁,我对自己写代码的规范还是有信心的- -。代码不会写的很复杂,整个代码结构有很高的统一度,结构也比较简单清晰,方便理解。里面做了大量的封装...
  • 如何构建一个健壮的安卓应用 >本系列文章从基础规范、代码设计、框架设计和崩溃分析等角度去讨论如何建立一个健壮...好的, 新闻app的推送一定是做的最好的。我们通过研究各种竞品技术来使得我们的app更加优秀和易用。
  • 产品经理学习视频

    2018-07-27 14:21:07
    4-产品设计-交互设计.mp4 5-产品设计-视觉设计.mp4 产品设计.xmind 04.第四阶段:项目实战训练 1从零打造款社区web产品 款web社区产品.mp4 2从零打造款工具app产品 款工具app产品.mp4 3怎么做款O2O互联网...
  • XpZC新普众筹系统 v2.0

    2019-10-26 04:30:42
    1、使用ASP.Net MVC、领域驱动设计模式2、限制国内IP访问功能3、MSSQL数据库4、UTF-8编码,可用于全球的服务器5、支持在线备份MSSQL数据库6、拥有三大配套前端:PC前端+微信WEB端+APP7、拥有伪静态技术8、缓存技术...
  • 基本遵循Google Material Design设计风格 透明状态栏使用与版本适配 图片加载picasso,Glide加载监听,获取缓存,圆角图片,高斯模糊 list条目点击水波纹效果 CoordinatorLayout+Behavior实现标题栏渐变 自定义...
  • imageslr/weapp-library ★300+ - 在线借书平台(WeUI设计规范、前后端开源、RESTful API文档) myronliu347/wechat-app-zhihudaily ★200+ - 知乎日报 harveyqing/BearDiary ★200+ - 小熊の日记 leancloud/...

空空如也

空空如也

1 2 3 4
收藏数 75
精华内容 30
关键字:

新闻app设计规范