• 团队项目——第一阶段冲刺8


    一、前言

    1.昨天完成了:

    将用户爱好选择存入数据库

    2.今天完成了:

     重构布局

    3.明天的计划:

    整合界面

    二、成果展示

     三、代码

    1.爱好选择布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:custom="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:background="#38353D"
            android:gravity="center"
            android:text="标签"
            android:textColor="@android:color/white"
            android:textSize="16dp" />
    
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
    
                <TextView
                    android:id="@+id/tv_remind"
                    android:layout_width="match_parent"
                    android:layout_height="46dp"
                    android:background="@android:color/white"
                    android:gravity="center_vertical"
                    android:paddingLeft="15dp"
                    android:text="我的标签(最多5个) "
                    android:textSize="16dp" />
    
                <com.me.view.FlowLayout
                    android:id="@+id/tcy_my_label"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@android:color/white"
                    android:padding="5dp"
                    android:visibility="gone"
                    custom:horizontalSpacing="6dp"
                    custom:verticalSpacing="12dp" />
    
                <View
                    android:layout_width="match_parent"
                    android:layout_height="10dp"
                    android:background="#f6f6f6" />
    
                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="46dp"
                    android:background="@android:color/white">
    
                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_centerVertical="true"
                        android:paddingLeft="15dp"
                        android:text="推荐标签 "
                        android:textSize="16dp" />
                </RelativeLayout>
    
                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="#f6f6f6" />
    
                <com.me.view.FlowLayout
                    android:id="@+id/tcy_hot_label"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@android:color/white"
                    android:padding="5dp"
                    custom:horizontalSpacing="6dp"
                    custom:verticalSpacing="12dp" />
            </LinearLayout>
        </ScrollView>
        <Button
            android:id="@+id/bt_sub"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="提交"
            android:layout_margin="5dp"/>
    </LinearLayout>
    View Code

    2.登录布局

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <EditText
            android:id="@+id/editTextPhoneNum"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="手机号"
            android:inputType="textPersonName"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.161"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.11" />
    
        <Button
            android:id="@+id/buttonCode"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="获取验证码"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.914"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.105"
            tools:text="获取验证码" />
    
        <EditText
            android:id="@+id/editTextCode"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="验证码"
            android:importantForAutofill="no"
            android:inputType="textPersonName"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.161"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.215" />
    
        <Button
            android:id="@+id/buttonLogin"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="登录"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.897"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.21" />
    
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_begin="568dp"
            app:layout_constraintGuide_percent="0.85" />
    
        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.193"
            app:layout_constraintStart_toStartOf="parent"
            app:srcCompat="@drawable/wx_" />
    
        <ImageView
            android:id="@+id/imageView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.793"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline3"
            app:layout_constraintVertical_bias="1.0"
            app:srcCompat="@drawable/qq" />
    
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_begin="578dp"
            app:layout_constraintGuide_percent="0.75" />
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="-----------其它方式-----------"
            android:textSize="18sp"
            app:layout_constraintBottom_toTopOf="@+id/guideline3"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline4" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    View Code

    3.爱好

    public class FlowLayout extends ViewGroup {
    
        //每个item纵向间距
        private int mVerticalSpacing;
        //每个item横向间距
        private int mHorizontalSpacing;
        private BaseAdapter mAdapter;
        private TagItemClickListener mListener;
        private DataChangeObserver mObserver;
    
        public FlowLayout(Context context) {
            this(context, null);
        }
    
        public FlowLayout(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public FlowLayout(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            //获取自定义样式属性
            TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.FlowLayout, defStyle, 0);
            for (int i = 0; i < a.getIndexCount(); i++) {
                int attr = a.getIndex(i);
                switch (attr) {
                    case R.styleable.FlowLayout_verticalSpacing:
                        mVerticalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_verticalSpacing, 5);
                        break;
                    case R.styleable.FlowLayout_horizontalSpacing:
                        mHorizontalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_horizontalSpacing, 10);
                        break;
                }
            }
            a.recycle();
        }
    
    
        //负责设置子控件的测量模式和大小 根据所有子控件设置自己的宽和高
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
            // 获得此ViewGroup上级容器为其推荐的宽和高,以及计算模式
            int heighMode = MeasureSpec.getMode(heightMeasureSpec);
            int heighSize = MeasureSpec.getSize(heightMeasureSpec);
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            //
            int height = 0;
            // 每一行的高度,累加至height
            int lineHeight = 0;
            // 在warp_content情况下,记录当前childView的左边的一个位置
            int childLeft = getPaddingLeft();
            // 在warp_content情况下,记录当前childView的上边的一个位置
            int childTop = getPaddingTop();
            // getChildCount得到子view的数目,遍历循环出每个子View
            for (int i = 0; i < getChildCount(); i++) {
                //拿到index上的子view
                View childView = getChildAt(i);
                // 测量每一个child的宽和高
                measureChild(childView, widthMeasureSpec, heightMeasureSpec);
                //当前子空间实际占据的高度
                int childHeight = childView.getMeasuredHeight();
                //当前子空间实际占据的宽度
                int childWidth = childView.getMeasuredWidth();
                lineHeight = Math.max(childHeight, lineHeight);// 取最大值
                //如果加入当前childView,超出最大宽度,则将目前最大宽度给width,类加height 然后开启新行
                if (childWidth + childLeft + getPaddingRight() > widthSize) {
                    childLeft = getPaddingLeft();// 重新开启新行,开始记录childLeft
                    childTop += mVerticalSpacing + childHeight;// 叠加当前的高度
                    lineHeight = childHeight;// 开启记录下一行的高度
                } else {
                    //否则累加当前childView的宽度
                    childLeft += childWidth + mHorizontalSpacing;
                }
            }
            height += childTop + lineHeight + getPaddingBottom();
            setMeasuredDimension(widthSize, heighMode == MeasureSpec.EXACTLY ? heighSize : height);
        }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            int width = r - l;
            int childLeft = getPaddingLeft();
            int childTop = getPaddingTop();
            int lineHeight = 0;
            //遍历所有childView根据其宽和高,计算子控件应该出现的位置
            for (int i = 0; i < getChildCount(); i++) {
                final View childView = getChildAt(i);
                if (childView.getVisibility() == View.GONE) {
                    continue;
                }
                int childWidth = childView.getMeasuredWidth();
                int childHeight = childView.getMeasuredHeight();
                lineHeight = Math.max(childHeight, lineHeight);
                // 如果已经需要换行
                if (childLeft + childWidth + getPaddingRight() > width) {
                    childLeft = getPaddingLeft();
                    childTop += mVerticalSpacing + lineHeight;
                    lineHeight = childHeight;
                }
                childView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
                childLeft += childWidth + mHorizontalSpacing;
            }
        }
    
        private void drawLayout() {
            if (mAdapter == null || mAdapter.getCount() == 0) {
                return;
            }
            removeAllViews();
            for (int i = 0; i < mAdapter.getCount(); i++) {
                View view = mAdapter.getView(i, null, null);
                final int position = i;
                view.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (mListener != null) {
                            mListener.itemClick(position);
                        }
                    }
                });
                addView(view);
            }
        }
    
        public void setAdapter(BaseAdapter adapter) {
            if (mAdapter == null) {
                mAdapter = adapter;
                if (mObserver == null) {
                    mObserver = new DataChangeObserver();
                    mAdapter.registerDataSetObserver(mObserver);
                }
                drawLayout();
            }
        }
    
        public void setItemClickListener(TagItemClickListener mListener) {
            this.mListener = mListener;
        }
    
        public interface TagItemClickListener {
            void itemClick(int position);
        }
    
        class DataChangeObserver extends DataSetObserver {
            @Override
            public void onChanged() {
                drawLayout();
            }
    
            @Override
            public void onInvalidated() {
                super.onInvalidated();
            }
        }
    }
    标签选择

    4.登录

    public class LoginActivity extends AppCompatActivity {
        private Button buttonCode,buttonLogin;
        private EditText editTextPhoneNum,editTextCode;
        private String phoneNum,code;
        private EventHandler eh;
        private MyCountDownTimer myCountDownTimer = new MyCountDownTimer(30000,1000);
        private SentUrlTask sentUrlTask ;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_login);
            buttonCode = findViewById(R.id.buttonCode);
            buttonLogin = findViewById(R.id.buttonLogin);
            editTextCode = findViewById(R.id.editTextCode);
            editTextPhoneNum = findViewById(R.id.editTextPhoneNum);
    
            buttonCode.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    phoneNum = editTextPhoneNum.getText().toString();
                    if(!phoneNum.isEmpty()){
                        if(Check.checkTel(phoneNum)){ //利用正则表达式获取检验手机号
                            // 获取验证码
                            SMSSDK.getVerificationCode("86", phoneNum);
                            myCountDownTimer.start();
                        }else{
                            Toast.makeText(getApplicationContext(),"请输入有效的手机号",Toast.LENGTH_LONG).show();
                        }
                    }else {
                        Toast.makeText(getApplicationContext(),"请输入手机号",Toast.LENGTH_LONG).show();
                        return;
                    }
                    phoneNum = editTextPhoneNum.getText().toString();
                }
            });
            buttonLogin.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    code = editTextCode.getText().toString();
                    if(!code.isEmpty()){
                        //提交验证码
                        SMSSDK.submitVerificationCode("86", phoneNum, code);
                    }else{
                        Toast.makeText(getApplicationContext(),"请输入验证码",Toast.LENGTH_LONG).show();
                        return;
                    }
                }
            });
    
            eh = new EventHandler() {
    
                @Override
                public void afterEvent(int event, int result, Object data) {
    
    
    
                    if (result == SMSSDK.RESULT_COMPLETE){
                        //回调完成
                        if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {
                            //提交验证码成功
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    success(phoneNum);
                                    Toast.makeText(LoginActivity.this,"登录成功",Toast.LENGTH_SHORT).show();
                                    Intent intent = new Intent(LoginActivity.this, BottomNavigationActivity.class);
                                    startActivity(intent);
                                }
                            });
                        }else if (event == SMSSDK.EVENT_GET_VOICE_VERIFICATION_CODE){
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(LoginActivity.this,"语音验证发送",Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
                        else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE){
                            //获取验证码成功
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(LoginActivity.this,"验证码已发送",Toast.LENGTH_SHORT).show();
                                }
                            });
                        }else if (event == SMSSDK.EVENT_GET_SUPPORTED_COUNTRIES){
                        }
                    }else{
                        ((Throwable)data).printStackTrace();
                        Throwable throwable = (Throwable) data;
                        throwable.printStackTrace();
                        try {
                            JSONObject obj = new JSONObject(throwable.getMessage());
                            final String des = obj.optString("detail");
                            if (!TextUtils.isEmpty(des)){
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        Toast.makeText(LoginActivity.this,des,Toast.LENGTH_SHORT).show();
                                    }
                                });
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
    
            //注册一个事件回调监听,用于处理SMSSDK接口请求的结果
            SMSSDK.registerEventHandler(eh);
    
        }
        // 使用完EventHandler需注销,否则可能出现内存泄漏
        @Override
        protected void onDestroy() {
            super.onDestroy();
            SMSSDK.unregisterEventHandler(eh);
        }
        //倒计时类
        private class MyCountDownTimer extends CountDownTimer {
    
            public MyCountDownTimer(long millisInFuture, long countDownInterval) {
                super(millisInFuture, countDownInterval);
            }
    
            //计时过程
            @Override
            public void onTick(long l) {
                //防止计时过程中重复点击
                buttonCode.setClickable(false);
                buttonCode.setText(l/1000+"秒");
    
            }
    
            //计时完毕的方法
            @Override
            public void onFinish() {
                //重新给Button设置文字
                buttonCode.setText("重新获取");
                //设置可点击
                buttonCode.setClickable(true);
            }
        }
        public void success(String username){
            sentUrlTask = new SentUrlTask("http://192.168.1.17:8080/NewsApi/news?method=addUser&username="+username);
    //        sentUrlTask = new ListFragment.SentUrlTask("http://192.168.43.243:8080/NewsApi/news?method=allnews");
            sentUrlTask.execute();
        }
    
        private class SentUrlTask extends AsyncTask<Void,Void,String> {
    
            private  String url;
    
            public SentUrlTask(String url) {
                this.url = url;
            }
    
            @Override
            protected String doInBackground(Void... voids) {
                return HttpUtil.setUrl(url);
            }
    
            @Override
            protected void onPostExecute(@NonNull String s) {
                super.onPostExecute(s);
            }
        }
    
    }
    View Code
  • 相关阅读:
    python 集合 set
    Meet Python
    Python 模块
    KNN
    Python Numpy包安装
    R分词
    Maximum Entropy Model(最大熵模型)初理解
    Conditional Random Fields (CRF) 初理解
    Naive Bayes (NB Model) 初识
    Hidden Markov Models(HMM) 初理解
  • 原文地址:https://www.cnblogs.com/best-hym/p/12755772.html
Copyright © 2020-2023  润新知