超酷的计步器APP——炫酷功能实现,自定义水波纹特效、自定义炫酷开始按钮、属性动画的综合体验

超酷的计步器APP——炫酷功能实现,自定义水波纹特效、自定义炫酷开始按钮、属性动画的综合体验

好久没写博客了,没给大家分享技术了,真是有些惭愧。这段时间我在找工作,今年Android的行情也不怎么好,再加上我又是一个应届生,所以呢,更是不好找了。但是我没有放弃,经过自己的不懈努力,还是找到了自己喜欢的Android工作,心里的一块石头终于落下了。但是迎接我来的是更多的挑战,我喜欢那种不断的挑战自我,在困难中让自己变得更强大的感觉。相信阳光总在风雨后,因为每一个你不满意的现在,都有一个你没有努力的曾经。所以我们一起努力,为了生活,生下来、活下去。


今天我们来一起学习一个很酷的小项目——计步器。

关于这个项目我想分两篇博客来和大家分享,一篇先来学习界面和功能中用到的自定义控件,下篇来实现动画和计步器连接起来开始计算步数的效果

我们先来看效果图。

是不是很酷很炫呢,哈哈,我觉得酷酷哒。

那么我们今天先来学习那个很酷的效果图的实现。

点击开始按钮,出现结束和暂停按钮,开始按钮隐藏,横线变波浪的效果

我们先新建一个Android项目,开始在main_activity.xml中书写布局

先来看这个布局的Component Tree

我们来写他的布局

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/activity_walking_backgroud"
        android:orientation="vertical">

        <include layout="@layout/top_bar" />

        <TextView
            android:id="@+id/step_count"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="90dp"
            android:textColor="@color/white"
            android:textSize="70sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="18dp"
            android:text="计算步数"
            android:textColor="@color/white"
            android:textSize="13sp" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="35dp"
            android:layout_marginLeft="30dp"
            android:layout_marginRight="50dp"
            android:layout_marginTop="60dp"
            android:orientation="horizontal"
            android:weightSum="2">

            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1">

                <ImageView
                    android:id="@+id/iv_calories"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentLeft="true"
                    android:src="@mipmap/calories" />

                <TextView
                    android:id="@+id/calories"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_toRightOf="@id/iv_calories"
                    android:textColor="@color/white"
                    android:textSize="24sp" />

                <TextView
                    android:id="@+id/tv_calories"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_below="@id/calories"
                    android:layout_toRightOf="@id/iv_calories"
                    android:text="热量:千卡"
                    android:textColor="@color/white"
                    android:textSize="10sp" />
            </RelativeLayout>

            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1">

                <ImageView
                    android:id="@+id/iv_time"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerHorizontal="true"
                    android:src="@mipmap/time" />

                <TextView
                    android:id="@+id/time"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_toRightOf="@id/iv_time"
                    android:text="0"
                    android:textColor="@color/white"
                    android:textSize="24sp" />

                <TextView
                    android:id="@+id/tv_time"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_below="@id/time"
                    android:layout_toRightOf="@id/iv_time"
                    android:text="时间:分钟"
                    android:textColor="@color/white"
                    android:textSize="10sp" />
            </RelativeLayout>

        </LinearLayout>
    </LinearLayout>

    <com.adu.running.view.WaveView
        android:id="@+id/wave_view"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_marginTop="-20dp"
        />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="30dp"
        android:layout_marginTop="27dp">

        <com.adu.running.view.CircleButton
            android:id="@+id/stop"
            android:layout_width="94dp"
            android:layout_height="94dp"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:layout_gravity="center"
            android:text="结束"
            android:textColor="@color/white"
            android:visibility="gone"/>

        <com.adu.running.view.CircleWaveButton
            android:id="@+id/start"
            android:layout_width="94dp"
            android:layout_height="94dp"
            android:layout_centerInParent="true"
            android:textColor="@color/white"/>

        <com.adu.running.view.CircleButton
            android:id="@+id/bt_continue"
            android:layout_width="94dp"
            android:layout_height="94dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_gravity="center"
            android:text="暂停"
            android:textColor="@color/white"
            android:visibility="gone"/>
        </RelativeLayout>

</LinearLayout>

如果你直接复制上面的代码到你的项目中肯定会报错的,因为上面的布局中我们引用了一个自定义的toolbar布局和几个颜色值,还有几个自定义View

一会我会把代码给大家传上去,或者直接看我GitHub上面的源码

我们现在看下面的三个自定义View怎么来完成的

WaveView.java自定义波纹类

package com.adu.running.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by adu on 2016/10/30.
 */

public class WaveView extends View {

    //波纹颜色
    private int waveColor = 0xff0099CC;
    // 振幅
    private float swing = 0;
    private int height;
    private int width;
    private int ms = 30;
    private float isPause=0f;
    private boolean isRun = false;
    //绘制波纹的画笔
    private Paint wavePaint;

    //Path类可以预先在View上将N个点连成一条"路径"
    // 然后调用Canvas的drawPath(path,paint)即可沿着路径绘制图形
    private Path path1;
    private Path path2;
    private Path path3;

    public WaveView(Context context) {
        super(context);
        init();
    }

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

    public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        // 初始绘制波纹的画笔
        wavePaint = new Paint();
        // 去除画笔锯齿
        wavePaint.setAntiAlias(true);
        //设置画笔颜色
        wavePaint.setColor(waveColor);
        //设置线宽
        wavePaint.setStrokeWidth(5);
        //设置风格为空心
        wavePaint.setStyle(Paint.Style.STROKE);
        path1 = new Path();
        path2 = new Path();
        path3 = new Path();
    }

    /**
     * 计算view高度宽度大小
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        initLayoutParams();
    }
    private void initLayoutParams() {
        height = this.getHeight();
        width = this.getWidth();
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        setPath();
        wavePaint.setStrokeWidth(6);
        wavePaint.setAlpha(100);//设置透明度
        canvas.drawPath(path1, wavePaint);

        wavePaint.setStrokeWidth(3);
        wavePaint.setAlpha(80);
        canvas.drawPath(path2, wavePaint);

        wavePaint.setAlpha(60);
        canvas.drawPath(path3, wavePaint);
    }

    /**
     * 设置三个线条上下震动的振幅
     */
    private void setPath() {
        int x = 0;
        int y = 0;
        path1.reset();//清除掉path里的线条和曲线
        for (int i = 0; i < width; i++) {
            x = i;
            y = (int) (isPause*40* Math.sin(i * 2*0.7f * Math.PI / width+swing) + height*0.5);
            if (i == 0) {
                path1.moveTo(x, y);//定位绘画开始位置
            }
            //绘制圆滑曲线,即贝塞尔曲线;(x, y)为控制点,(x + 1, y)为结束点
            path1.quadTo(x, y, x + 1, y);
        }
        path2.reset();
        for (int i = 0; i < width; i++) {
            x = i;
            y = (int) (isPause*40* Math.sin(i * 2*0.7f * Math.PI / width+swing+0.3f) + height*0.5);
            if (i == 0) {
                path2.moveTo(x, y);
            }
            path2.quadTo(x, y, x + 1, y);
        }
        path3.reset();
        for (int i = 0; i < width; i++) {
            x = i;
            y = (int) (isPause*40* Math.sin(i * 2*0.7f * Math.PI / width+swing+0.3f) + height*0.5);
            if (i == 0) {
                path3.moveTo(x, y);
            }
            path3.quadTo(x, y, x + 1, y);
        }

        path1.close();//回到初始点形成封闭的曲线
        path2.close();
        path3.close();
    }

    public void start(){
        this.isRun=true;
        this.isPause=1.0f;
        new MyThread().start();//让波纹在子线程中运行
    }
    public void stop(){
        this.isRun=false;
        this.isPause=0.0f;
        invalidate();//请求重新绘制的界面
    }

    private class MyThread extends Thread {
        @Override
        public void run() {
            while (isRun) {
                swing+=-0.25f;
                mHandler.sendEmptyMessage(1);
                try {
                    Thread.sleep(ms);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1) {
                invalidate();//请求重新绘制的界面
            }
        }
    };
}

让我们在MainActivity的布局中新建两个Button按钮开对自定义波纹类进行测试,分别调用它的start( )和stop( )方法,运行结果如下:

点击开始,波纹会上下起伏,点击停止,它会恢复到停止状态

接着,我们看下面的三个按钮是怎么实现的,其实是两个自定义的Button

CircleWaveButton.java 开始按钮

package com.adu.running.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.widget.Button;
import com.adu.running.R;

/**
 * Created by adu on 2016/10/30.
 */

public class CircleWaveButton extends Button{

    //这是默认颜色
    private int paintColor= R.color.circle_bule_bbd4e7;
    //画圆的画笔
    private Paint paint = new Paint();
    //画字的画笔
    private Paint textPaint = new Paint();
    private int radiusInt = 0;
    //这是默认文字内容
    private String text="开始";
    private Boolean isStart = false;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            invalidate();
            if (isStart) {
                radiusInt++;
                if (radiusInt > 50) {
                    radiusInt = 0;
                }
                sendEmptyMessageDelayed(0, 20);
            }
        }
    };
    public CircleWaveButton(Context context) {
        super(context);
        init();
    }

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

    public CircleWaveButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setBackgroundColor(getResources().getColor(R.color.running));
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int centre = getWidth() / 2;
        int radius = centre;
        //绘制圆的画笔
        Paint newPaint = new Paint();
        newPaint.setAntiAlias(true);        // 去除画笔锯齿
        newPaint.setStyle(Paint.Style.FILL);// 设置风格为实线

        //用来进行环形渲染
        Shader shader = new RadialGradient(centre, centre, radius, getResources().getColor(paintColor), getResources().getColor(R.color.running), Shader.TileMode.CLAMP);
        //设置图像效果,使用Shader可以绘制出各种渐变效果
        newPaint.setShader(shader);
        //绘制圆形(圆心的x坐标,圆心的y坐标,圆的半径,绘制时所使用的画笔)
        canvas.drawCircle(centre, centre, radius, newPaint);

        paint.setColor(getResources().getColor(paintColor));
        paint.setStyle(Paint.Style.FILL);   //设置风格为实线
        paint.setAntiAlias(true);           // 去除画笔锯齿

        for(int i=1;i<=5;i++){
            paint.setAlpha(20*i);//设置绘制图形的透明度
            //绘制圆形(圆心的x坐标,圆心的y坐标,圆的半径,绘制时所使用的画笔)
            canvas.drawCircle(centre, centre, radius * (10- i)/ 10, paint);
        }

        paint.setColor(getResources().getColor(paintColor));
        paint.setStyle(Paint.Style.STROKE);     //设置风格为空心
        paint.setStrokeWidth(radius * 2 / 12);  //设置线宽

        for(int i=0;i<3;i++) {
            paint.setAlpha(60-i*20);//设置绘制图形的透明度
            //绘制圆形(圆心的x坐标,圆心的y坐标,圆的半径,绘制时所使用的画笔)
            canvas.drawCircle(centre, centre, radius * (14-i*2 + radiusInt / 50.0f) / 16, paint);
        }

        textPaint.setTextSize(getTextSize());
        textPaint.setAntiAlias(true);
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setColor(getTextColors().getDefaultColor());

        //获取文字的宽度值
        float length = textPaint.measureText(text);
        //绘制文字
        canvas.drawText(text, centre - length / 2, centre + getTextSize() / 3, textPaint);
    }
    public void start() {
        isStart = true;
        handler.sendEmptyMessage(0);
    }

    public void stop() {
        isStart = false;
        handler.removeMessages(0);
    }
}

我们在MainActivity设置CircleWaveButton的点击事件调用它的start( )方法,会看到下面的效果

下面我们看最后一个自定义Button,结束的Button和暂停的Button只是颜色不一样,其他都是一样的。

CircleButton.xml暂停结束按钮

package com.adu.running.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.Button;
import com.adu.running.R;

/**
 * Created by adu on 2016/10/30.
 */

public class CircleButton extends Button {
    //画圆
    private Paint paint = new Paint();
    //画字
    private Paint textPaint = new Paint();

    private int color;

    public CircleButton(Context context) {
        super(context);
        init();
    }
    public CircleButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    public CircleButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setBackgroundColor(getResources().getColor(R.color.running));
        color=getResources().getColor(R.color.running);
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int centre = getWidth() / 2;
        int radius = centre;

        paint.setColor(color);
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true);
        //绘制圆形(圆心的x坐标,圆心的y坐标,圆的半径,绘制时所使用的画笔)
        canvas.drawCircle(centre, centre, radius, paint);

        textPaint.setTextSize(getTextSize());
        textPaint.setAntiAlias(true);
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setColor(getTextColors().getDefaultColor());

        float length = textPaint.measureText(getText().toString());
        //绘制文字
        canvas.drawText(getText().toString(), centre - length / 2, centre + getTextSize() / 3, textPaint);
    }
    //改变文字颜色
    public void setPaintColor(int color) {
        this.color = getResources().getColor(color);
    }
}

我们就不在测试这个Button了,直接写开始的那个效果

点击开始按钮,然后隐藏它,一个动画的效果出现结束和暂停按钮,并且开启波纹,点暂停波纹停止,点击结束退出。

我们之间在MainActivity中写代码

package com.adu.running;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Point;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.DecelerateInterpolator;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import com.adu.running.view.CircleButton;
import com.adu.running.view.CircleWaveButton;
import com.adu.running.view.WaveView;

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.wave_view) WaveView waveView;
    @BindView(R.id.startButton) CircleWaveButton startButton;   //开始
    @BindView(R.id.stop) CircleButton stopButton;               //停止
    @BindView(R.id.bt_continue) CircleButton btContinue;        //暂停继续

    private boolean isPause = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        initView();
    }

    private void initView() {

        btContinue.setPaintColor(R.color.text_color_1e78be);
        startButton.setPaintColor(R.color.circle_bule_bbd4e7);
        stopButton.setPaintColor(R.color.circle_red_cd3a33);
        startButton.start();

    }

    @OnClick({ R.id.stop, R.id.startButton, R.id.bt_continue })
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.stop:     //停止并退出
                System.exit(0);
                break;
            case R.id.startButton:  //开始
                startAnimation();
                waveView.start();
                break;
            case R.id.bt_continue:  //暂停继续

                if (isPause){
                    btContinue.setText("暂停");
                    isPause = false;
                    waveView.start();
                }else {
                    btContinue.setText("继续");
                    isPause = true;
                    waveView.stop();
                }
                break;
        }
    }

    /**
     * 按钮动画效果实现的方法
     */
    private void startAnimation() {
        btContinue.setVisibility(View.VISIBLE);//显示暂停按钮
        stopButton.setVisibility(View.VISIBLE);//显示停止按钮
        //获取屏幕的大小,并把屏幕的宽也就是x赋值给width
        WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        int width = size.x;

        //属性动画,传入"alpha"参数,将开始按钮从不透明改变为透明
        Animator animatorStart = ObjectAnimator.ofFloat(startButton, "alpha", 1.0f, 0f);
        AnimatorSet animatorSetStart = new AnimatorSet();//组合动画
        animatorSetStart.playTogether(animatorStart);
        animatorSetStart.setInterpolator(new DecelerateInterpolator());//动画效果设置为减速
        animatorSetStart.setDuration(1000);//设置动画时长

        //将暂停按钮由透明改变为不透明
        Animator animatorContinue1 = ObjectAnimator.ofFloat(btContinue, "alpha", 0f, 1.0f);
        animatorContinue1.setDuration(3000);//设置动画时长
        //将暂停按钮从中间向右边移动
        Animator animatorContinue2 = ObjectAnimator.ofFloat(btContinue, "translationX", -width / 3, btContinue.getX());
        animatorContinue2.setDuration(2000);//设置动画时长
        AnimatorSet animatorSetContinue = new AnimatorSet();
        animatorSetContinue.playTogether(animatorContinue1, animatorContinue2);// 并行
        animatorSetContinue.setInterpolator(new DecelerateInterpolator());//动画效果设置为减速

        //将结束按钮由透明改变为不透明
        Animator animatorStop1 = ObjectAnimator.ofFloat(stopButton, "alpha", 0f, 1.0f);
        animatorStop1.setDuration(3000);//设置动画时长
        //将结束按钮从中间向左边移动
        Animator animatorStop2 = ObjectAnimator.ofFloat(stopButton, "translationX", width / 3, 0);
        animatorStop2.setDuration(2000);//设置动画时长
        AnimatorSet animatorSetStop = new AnimatorSet();
        animatorSetStop.playTogether(animatorStop1, animatorStop2);// 并行
        animatorSetStop.setInterpolator(new DecelerateInterpolator());//动画效果设置为减速

        //启动三个按钮动画
        animatorSetStart.start();
        animatorSetStop.start();
        animatorSetContinue.start();

        startButton.setVisibility(View.GONE);
    }
}

我们运行代码,看看效果

我们就简单的完成了一个这样的动画效果,看起来还是蛮酷的嘛。


这篇博客,我们主要学习了三个自定义View的实现,然后组合在一起形成一个很酷的效果。

下篇博客,我开始给大家讲这个动画和计步器连接起来开始计算步数的效果

我把这篇博客的Demo上传到这里,如果想直接看完整的动画和计步器的代码,请大家看我的GitHub,如果喜欢的话可以star一下,谢谢大家的支持

点击下载Demo

时间: 2024-10-14 06:49:13

超酷的计步器APP——炫酷功能实现,自定义水波纹特效、自定义炫酷开始按钮、属性动画的综合体验的相关文章

6种炫酷的CSS3按钮边框动画特效

这是一款效果非常炫酷的CSS3按钮边框动画特效.这组按钮边框动画共有6种不同的效果.当鼠标滑过按钮的时候,按钮的边框会以不同的方式进行各种动画,效果非常的炫酷. 在线预览   源码下载 使用方法 HTML结构 该CSS3按钮边框动画特效中的按钮使用HTML的<button>元素来制作.各种效果非标设置不同的class.例如第一种效果的class为draw. <button class="draw">draw</button> CSS样式 在CSS样式

说说酷播云存储及数据分析功能(多图)

说说酷播云存储及数据分析功能(多图) 酷播云的统计分析功能截图,什么是酷播云?就是可以上传视频,上传后,就可以直接调用播放的一个平台,最大特色是无广告,不像youku,tudou视频前面会加一段70秒的广告. 第1步:登陆酷播云管理平台后,点击顶部导航栏的"数据统计",界面如下. 第2步:这个界面即显示您站点中播放视频的基本数据情况. 地理位置 第1步:登陆酷播云管理平台后,点击顶部导航栏的"数据统计",界面如下. 第2步:点击左侧"地理位置".

cocos2d 2.x在opengl es 2.0 下自定义着色器来创建特别酷的特效(译)

cocos2d 2.x在opengl es 2.0 下自定义着色器来创建特别酷的特效(译) (2012-12-24 13:22:17) 转载▼ 标签: it cocos2d opengl 着色器 渲染 翻译:弹涂鱼 PS:欢迎加入开发群:285275050 本文翻译自:http://www.raywenderlich.com/10862/how-to-create-cool-effects-with-custom-shaders-in-opengl-es-2-0-and-cocos2d-2-x#

打造支持apk下载和html5缓存的 IIS(配合一个超简单的android APP使用)具体解释

为什么要做这个看起来不靠谱的东西呢? 由于刚学android开发,还不能非常好的熟练控制android界面的编辑和操作,所以我的一个急着要的运用就改为html5版本号了,反正这个运用也是须要从server获取大量数据来展示在手机上面的,也就是说:必须联网,才干正常工作,于是想了一下,反正都要联网获取数据,为什么不直接用我相对熟悉一点的 html来做这个运用呢?省的花费不够用的时间去学习android界面的控制,于是就简单了:用蹩脚的手段做了一个android程序的启动欢迎界面,内页就是一个全屏的

20 行代码极速为 App 加上聊天功能

现在很多 App 都需要集成 IM 功能,今天就为大家分享一下集成 IM 基本功能的步骤.本文内容以 JMessage 为例.极光 IM ( JMessage ) = 极光推送 ( JPush ) + IM,本篇只论述其中的 IM 部分,为大家快速集成 IM 功能提供一个简明的范例. 我们先来看一下 IM 的基本功能与本文内容的对应关系: line 0:准备工作 下载 SDK 集成 SDK line 1:引入头文件 #import <JMessage/JMessage.h> JMessage

手机教育APP开发,功能和难点详解

从2016年下半年开始,有关内容的创业逐渐多了起来.付费内容成为了焦点话题,应运而生的各类教育APP层出不穷.那么,教育APP的开发难点在哪里?如何开发出一款高质量的教育APP呢? 一. 教育APP开发难点 英语学习和面向K12市场的APP最受关注,孩子的教育是永恒的话题.而一款日常学习.作业,习题等考试的APP开发有以下难点: 1.       更新难点: 众所周知,教育APP的内容量巨大,且繁杂.尤其是针对学生使用的APP,既有数学公式,也有化学图形:既有语文古文,又是外语习题,而且还要分年

常规功能和模块自定义系统 (cfcmms)—019自定义grid方案(3)

常规功能和模块自定义系统 (cfcmms)-019自定义grid方案(3) 这一节开始进入自定义的内部,来看看第一个自定义的功能是如何实现的. 1?在系统登录的时候,将所有的登录用户有权限的模块定义信息全部发送到前端.这段代码在app/view/main/MainModel.js中.在MainModel创建的时候,通过会发送一个同步的ajax请求来获取数据.取得数据后将所有的module信息放到MainView的data中. Ext.Ajax .request({ url : 'applicat

常规功能和模块自定义系统 (cfcmms)—018自定义grid方案(2)

常规功能和模块自定义系统 (cfcmms)-018自定义grid方案(2) 下面来看看在系统中如何定义一个grid方案.当前定义grid方案也是采用对记录模块操作的方式,并没有采用所见即所得得的设计方式,以后有时间将会修改成所见即所得得方式. 上图中可以看到在进入了"模块列表方案"后,会显示所有的模块的列表方案,在导航里选择了"省份"这后,会只显示省份的2个列表方案.每个方案都有若干个字段组,选中一条记录以后,按"列表字段分组"可以看到当前方案的

ERP小型集团化——重点功能及二次开发配置——自定义业务

客户帐套配置小型集团化后,审批相关功能的使用和以前有些差别:二次开发的suite工具中,部分功能也设置了数据同步(工具中带※图案的功能),即这些配置信息全部保存在了集团数据库中. 注意:建议带※标识的功能集团帐套的Suite中创建!!! 以下是和以前使用方式有变化的功能的介绍,未介绍的功能使用方式不变: 1.  审批 2.  查询 3.  自定义业务 4.  清单查找/树形查找(无※) 5.  移动OA及二次开发(商业智能) 6.  单据直送 7.  其他 ...................