Android Studio App开发实战项目之淘宝评价晒单(附源码 超详细必看 简单易懂)

简介: Android Studio App开发实战项目之淘宝评价晒单(附源码 超详细必看 简单易懂)

需要源码或有问题请点赞关注收藏后评论区留言~~~

电商App经常会和用户互动,虚心听取用户的意见,同样的,我们在买东西的时候也会着重看一看货物的评价然后货比三家,评价内容可以是纯文字,也可以是图片甚至是带视频的评价。

一、需求描述

用户在评价页面可以选择评分等级,输入文字评价,还能点击加号按钮上传图片或者视频 效果如下,并且可以提交评价,然后我们运行展示类即可看到提交的评价

填写评价和等级 五星好评

 

一星差评

选择文件或者视频

二、界面设计

商品评价不单单是文字内容,还包括图片晒单与视频晒单,所以用到了以下技术

拍照

查找相册

查看图片

录制视频

查找视频库

播放视频

同样 用户提交的图片可能很大,为了导致系统崩溃和浪费资源,App需要采取图片压缩技术,适当缩小用户的大图 以便提升App的运行性能

三、关键部分

1:如何使用评分条控件RatingBar

评价商品时的星级选择用到了评分条RatingBar,它由若干个五角星组成,总数表示评价总分,高亮的五角星数量表示当前评分

RatingBar有两种用法 一种是评价的时候允许改变星级,另一种是展示星级的时候不允许改变星级

2:在活动页面之间传递图形数据

3:评价晒单项目的源码之间关系

1:GoodsOrderActivity 这是订单列表的活动代码 列出了相关信息

2:EvaluateGoodsActivity 这是填写评价的活动代码

3:EvaluateDetailActivity 这是评价详情的活动代码

4:EvaluatePhotoActivity  这是浏览晒图的活动代码

四、代码

Java类

填写评价类

package com.example.chapter13;
import android.content.ContentValues;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.chapter13.bean.EvaluateInfo;
import com.example.chapter13.bean.EvaluatePhoto;
import com.example.chapter13.bean.GoodsOrder;
import com.example.chapter13.database.EvaluateInfoHelper;
import com.example.chapter13.database.EvaluatePhotoHelper;
import com.example.chapter13.database.GoodsOrderHelper;
import com.example.chapter13.util.BitmapUtil;
import com.example.chapter13.util.DateUtil;
import com.example.chapter13.util.FileUtil;
import java.util.ArrayList;
import java.util.List;
public class EvaluateGoodsActivity extends AppCompatActivity implements View.OnClickListener {
    private final static String TAG = "EvaluateGoodsActivity";
    private int COMBINE_CODE = 4; // 既可拍照获得现场图片、也可在相册挑选已有图片的请求码
    private TextView tv_hint;
    private RatingBar rb_score;
    private EditText et_comment;
    private ImageView iv_first;
    private ImageView iv_second;
    private ImageView iv_third;
    private ImageView iv_current;
    private GoodsOrder mOrder;
    private Uri mImageUri; // 图片的路径对象
    private List<String> mImageList = new ArrayList<String>(); // 图片文件的路径列表
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_evaluate_goods);
        TextView tv_title = findViewById(R.id.tv_title);
        tv_title.setText("评价商品");
        findViewById(R.id.iv_back).setOnClickListener(this);
        tv_hint = findViewById(R.id.tv_hint);
        rb_score = findViewById(R.id.rb_score);
        et_comment = findViewById(R.id.et_comment);
        iv_first = findViewById(R.id.iv_first);
        iv_second = findViewById(R.id.iv_second);
        iv_third = findViewById(R.id.iv_third);
        iv_first.setOnClickListener(this);
        iv_second.setOnClickListener(this);
        iv_third.setOnClickListener(this);
        findViewById(R.id.btn_commit).setOnClickListener(this);
        getGoodsOrder(); // 获取商品订单
    }
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.iv_back) {
            finish(); // 关闭当前页面
        } else if (v.getId() == R.id.iv_first) {
            openSelectDialog(v); // 打开选择对话框(要拍照还是去相册)
        } else if (v.getId() == R.id.iv_second) {
            openSelectDialog(v); // 打开选择对话框(要拍照还是去相册)
        } else if (v.getId() == R.id.iv_third) {
            openSelectDialog(v); // 打开选择对话框(要拍照还是去相册)
        } else if (v.getId() == R.id.btn_commit) {
            if (TextUtils.isEmpty(et_comment.getText())) {
                Toast.makeText(this, "请填写评价内容", Toast.LENGTH_SHORT).show();
                return;
            }
            commitEvaluate(); // 提交评价
        }
    }
    // 获取商品订单
    private void getGoodsOrder() {
        long order_id = getIntent().getLongExtra("order_id", -1);
        GoodsOrderHelper mOrderHelper = GoodsOrderHelper.getInstance(this);
        // 获取指定订单编号的商品订单
        List<GoodsOrder> mOrderList = (List<GoodsOrder>) mOrderHelper.queryByRowid(order_id);
        if (mOrderList.size() > 0) {
            mOrder = mOrderList.get(0);
            tv_hint.setText(String.format("请填写对%s的评价:", mOrder.goods_name));
        }
    }
    // 打开选择对话框(要拍照还是去相册)
    private void openSelectDialog(View v) {
        iv_current = (ImageView) v;
        // Android10开始必须由系统自动分配路径,同时该方式也能自动刷新相册
        ContentValues values = new ContentValues();
        values.put(MediaStore.Video.Media.DISPLAY_NAME, "photo_"+ DateUtil.getNowDateTime());
        values.put(MediaStore.Video.Media.MIME_TYPE, "image/jpeg"); // 类型为图像
        mImageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        // 声明相机的拍照行为
        Intent photoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // 往意图存入待拍摄的图片路径
        photoIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
        Intent[] intentArray = new Intent[] { photoIntent };
        // 声明相册的打开行为
        Intent albumIntent = new Intent(Intent.ACTION_GET_CONTENT);
        albumIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false); // 是否允许多选
        albumIntent.setType("image/*"); // 类型为图像
        // 容纳相机和相册在内的选择意图
        Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
        chooserIntent.putExtra(Intent.EXTRA_TITLE, "请拍照或选择图片");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
        chooserIntent.putExtra(Intent.EXTRA_INTENT, albumIntent);
        // 创建封装好标题的选择器意图
        Intent chooser = Intent.createChooser(chooserIntent, "选择图片");
        // 在页面底部弹出多种选择方式的列表对话框
        startActivityForResult(chooser, COMBINE_CODE);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        if (resultCode == RESULT_OK && requestCode == COMBINE_CODE) {
            Bitmap bitmap = getPhoto(intent); // 从照片获得位图对象
            iv_current.setImageBitmap(bitmap); // 设置图像视图的位图对象
            Log.d(TAG, "bitmap.getByteCount="+bitmap.getByteCount()+", bitmap.getWidth="+bitmap.getWidth()+", bitmap.getHeight="+bitmap.getHeight());
            addBitmapList(bitmap, R.id.iv_first, 0, iv_second);
            addBitmapList(bitmap, R.id.iv_second, 1, iv_third);
            addBitmapList(bitmap, R.id.iv_third, 2, null);
        }
    }
    // 添加到位图列表
    private void addBitmapList(Bitmap bitmap, int iv_id, int pos, ImageView iv_next) {
        if (iv_current.getId() == iv_id) {
            // 获得图片的临时保存路径
            String filePath = String.format("%s/%s.jpg",
                    getExternalFilesDir(Environment.DIRECTORY_PICTURES), "photo_"+ DateUtil.getNowDateTime());
            FileUtil.saveImage(filePath, bitmap); // 把位图保存为图片
            if (mImageList.size() <= pos) {
                mImageList.add(filePath);
            } else {
                mImageList.set(pos, filePath);
            }
            if (iv_next != null) {
                iv_next.setVisibility(View.VISIBLE);
            }
        }
    }
    // 从照片获得位图对象
    private Bitmap getPhoto(Intent intent) {
        Bitmap bitmap;
        if (intent!=null && intent.getData()!=null) { // 从相册选择一张照片
            Uri uri = intent.getData(); // 获得已选择照片的路径对象
            // 根据指定图片的uri,获得自动缩小后的位图对象
            bitmap = BitmapUtil.getAutoZoomImage(this, uri);
        } else { // 拍照的原始图片
            // 根据指定图片的uri,获得自动缩小后的位图对象
            bitmap = BitmapUtil.getAutoZoomImage(this, mImageUri);
        }
        return bitmap;
    }
    // 提交评价
    private void commitEvaluate() {
        mOrder.evaluate_status = 1;
        GoodsOrderHelper mOrderHelper = GoodsOrderHelper.getInstance(this);
        mOrderHelper.updateStatus(mOrder); // 更新该商品订单的评价状态
        saveEvaluateRecord(); // 保存评价记录
        finish(); // 关闭当前页面
    }
    // 保存评价记录
    private void saveEvaluateRecord() {
        EvaluateInfo info = new EvaluateInfo();
        info.order_id = mOrder.rowid;
        info.goods_name = mOrder.goods_name;
        info.evaluate_star = (int) rb_score.getRating();
        info.evaluate_content = et_comment.getText().toString();
        info.create_time = DateUtil.getNowDateTime();
        EvaluateInfoHelper infoHelper = EvaluateInfoHelper.getInstance(this);
        long evaluate_id = infoHelper.insert(info); // 插入评价记录
        EvaluatePhotoHelper photoHelper = EvaluatePhotoHelper.getInstance(this);
        for (String image_path : mImageList) {
            EvaluatePhoto photo = new EvaluatePhoto();
            photo.evaluate_id = evaluate_id;
            photo.image_path = image_path;
            photoHelper.insert(photo); // 插入评价图片
        }
    }
}

详情活动类

package com.example.chapter13;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.chapter13.bean.EvaluateInfo;
import com.example.chapter13.bean.EvaluatePhoto;
import com.example.chapter13.bean.GoodsOrder;
import com.example.chapter13.database.EvaluateInfoHelper;
import com.example.chapter13.database.EvaluatePhotoHelper;
import com.example.chapter13.database.GoodsOrderHelper;
import com.example.chapter13.util.DateUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class EvaluateDetailActivity extends AppCompatActivity implements View.OnClickListener {
    private TextView tv_name;
    private TextView tv_time;
    private RatingBar rb_score;
    private TextView tv_comment;
    private LinearLayout ll_photo;
    private ImageView iv_first;
    private ImageView iv_second;
    private ImageView iv_third;
    private long evaluate_id; // 评价编号
    private EvaluateInfo mEvaluate; // 评价信息
    private List<EvaluatePhoto> mPhotoList = new ArrayList<EvaluatePhoto>(); // 图片列表
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_evaluate_detail);
        TextView tv_title = findViewById(R.id.tv_title);
        tv_title.setText("评价详情");
        findViewById(R.id.iv_back).setOnClickListener(this);
        TextView tv_option = findViewById(R.id.tv_option);
        tv_option.setVisibility(View.VISIBLE);
        tv_option.setText("删除评价");
        tv_option.setOnClickListener(this);
        tv_name = findViewById(R.id.tv_name);
        tv_time = findViewById(R.id.tv_time);
        rb_score = findViewById(R.id.rb_score);
        tv_comment = findViewById(R.id.tv_comment);
        ll_photo = findViewById(R.id.ll_photo);
        iv_first = findViewById(R.id.iv_first);
        iv_second = findViewById(R.id.iv_second);
        iv_third = findViewById(R.id.iv_third);
        iv_first.setOnClickListener(this);
        iv_second.setOnClickListener(this);
        iv_third.setOnClickListener(this);
    }
    @Override
    protected void onResume() {
        super.onResume();
        evaluate_id = getIntent().getLongExtra("evaluate_id", -1);
        EvaluateInfoHelper infoHelper = EvaluateInfoHelper.getInstance(this);
        // 查询指定评价编号的评价记录
        List<EvaluateInfo> infoList = (List<EvaluateInfo>) infoHelper.queryByRowid(evaluate_id);
        if (infoList.size() > 0) {
            mEvaluate = infoList.get(0);
            tv_name.setText(mEvaluate.goods_name);
            tv_time.setText(DateUtil.convertDateString(mEvaluate.create_time));
            rb_score.setRating(mEvaluate.evaluate_star);
            tv_comment.setText(mEvaluate.evaluate_content);
        }
        EvaluatePhotoHelper photoHelper = EvaluatePhotoHelper.getInstance(this);
        // 查询指定评价编号的评价图片
        mPhotoList = photoHelper.queryByEvaluateId(evaluate_id);
        for (int i=0; i<mPhotoList.size(); i++) {
            ll_photo.setVisibility(View.VISIBLE);
            EvaluatePhoto photo = mPhotoList.get(i);
            showImage(photo.image_path, i); // 显示评价图片
        }
    }
    // 显示评价图片
    private void showImage(String image_path, int pos) {
        ImageView iv = null;
        if (pos == 0) {
            iv = iv_first;
        } else if (pos == 1) {
            iv = iv_second;
        } else if (pos == 2) {
            iv = iv_third;
        }
        if (iv != null) {
            iv.setVisibility(View.VISIBLE);
            iv.setImageURI(Uri.parse(image_path)); // 设置图像视图的图片路径
        }
    }
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.iv_back) {
            finish(); // 关闭当前页面
        } else if (v.getId() == R.id.tv_option) {
            deleteEvaluate(); // 删除当前评价
        } else if (v.getId() == R.id.iv_first) {
            openWholePhoto(0); // 打开整张图片
        } else if (v.getId() == R.id.iv_second) {
            openWholePhoto(1); // 打开整张图片
        } else if (v.getId() == R.id.iv_third) {
            openWholePhoto(1); // 打开整张图片
        }
    }
    // 删除当前评价
    private void deleteEvaluate() {
        updateEvaluateStatus(); // 更新评价状态(商品订单表的评价状态改为未评价)
        deleteEvaluateRecord(); // 删除评价记录
        finish(); // 关闭当前页面
    }
    // 更新评价状态(商品记录表的评价状态改为未评价)
    private void updateEvaluateStatus() {
        GoodsOrderHelper orderHelper = GoodsOrderHelper.getInstance(this);
        List<GoodsOrder> orderList = (List<GoodsOrder>) orderHelper.queryByRowid(mEvaluate.order_id);
        if (orderList.size() > 0) {
            GoodsOrder order = orderList.get(0);
            order.evaluate_status = 0;
            orderHelper.updateStatus(order);
        }
    }
    // 删除评价记录
    private void deleteEvaluateRecord() {
        EvaluateInfoHelper infoHelper = EvaluateInfoHelper.getInstance(this);
        infoHelper.deleteByRowid(evaluate_id);
        EvaluatePhotoHelper photoHelper = EvaluatePhotoHelper.getInstance(this);
        photoHelper.deleteByEvaluateId(evaluate_id);
        for (EvaluatePhoto photo : mPhotoList) {
            File file = new File(photo.image_path);
            file.delete(); // 删除存储卡上的图片文件
        }
        Toast.makeText(this, "已删除当前评价", Toast.LENGTH_SHORT).show();
    }
    // 打开整张图片
    private void openWholePhoto(int pos) {
        String image_path = mPhotoList.get(pos).image_path;
        // 下面跳到指定图片的浏览页面
        Intent intent = new Intent(this, EvaluatePhotoActivity.class);
        intent.putExtra("image_path", image_path); // 往意图中保存图片路径
        startActivity(intent); // 打开评价大图的页面
    }
}

浏览图片类

package com.example.chapter13;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
public class EvaluatePhotoActivity extends AppCompatActivity implements View.OnClickListener {
    private final static String TAG = "EvaluatePhotoActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_evaluate_photo);
        String image_path = getIntent().getStringExtra("image_path"); // 获取意图中的图片路径
        ImageView iv_photo = findViewById(R.id.iv_photo);
        iv_photo.setOnClickListener(this);
        iv_photo.setImageURI(Uri.parse(image_path)); // 设置图像视图的图片路径
    }
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.iv_photo) {
            finish(); // 关闭当前页面
        }
    }
}

XML文件

对应顺序同上Java类

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <include layout="@layout/title_evaluate" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5dp"
        android:orientation="vertical">
        <RatingBar
            android:id="@+id/rb_score"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:numStars="5"
            android:rating="3"
            android:stepSize="1" />
        <TextView
            android:id="@+id/tv_hint"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:gravity="left"
            android:text="请填写对**的评价:"
            android:textColor="@color/black"
            android:textSize="17sp" />
        <EditText
            android:id="@+id/et_comment"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="5dp"
            android:background="@drawable/editext_selector"
            android:gravity="left|top"
            android:hint="请填写评价文字"
            android:textColor="@color/black"
            android:textSize="17sp" />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="5dp"
            android:orientation="horizontal">
            <ImageView
                android:id="@+id/iv_first"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:layout_marginLeft="5dp"
                android:scaleType="fitXY"
                android:src="@drawable/add_pic"
                android:visibility="visible" />
            <ImageView
                android:id="@+id/iv_second"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:layout_marginLeft="5dp"
                android:scaleType="fitXY"
                android:src="@drawable/add_pic"
                android:visibility="gone" />
            <ImageView
                android:id="@+id/iv_third"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:layout_marginLeft="5dp"
                android:scaleType="fitXY"
                android:src="@drawable/add_pic"
                android:visibility="gone" />
        </LinearLayout>
        <Button
            android:id="@+id/btn_commit"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="提交评价"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </LinearLayout>
</LinearLayout>

2

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="商品名称:"
                android:textColor="@color/black"
                android:textSize="17sp" />
            <TextView
                android:id="@+id/tv_name"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:gravity="left"
                android:textColor="@color/black"
                android:textSize="17sp" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:orientation="horizontal">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="评价时间:"
                android:textColor="@color/black"
                android:textSize="17sp" />
            <TextView
                android:id="@+id/tv_time"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:gravity="left"
                android:textColor="@color/black"
                android:textSize="17sp" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:orientation="horizontal">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="评价星级:"
                android:textColor="@color/black"
                android:textSize="17sp" />
            <RatingBar
                android:id="@+id/rb_score"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:numStars="5"
                android:stepSize="1"
                android:isIndicator="true"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:orientation="horizontal">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="评价内容:"
                android:textColor="@color/black"
                android:textSize="17sp" />
            <TextView
                android:id="@+id/tv_comment"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:gravity="left"
                android:textColor="@color/black"
                android:textSize="17sp" />
        </LinearLayout>
        <LinearLayout
            android:id="@+id/ll_photo"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:orientation="horizontal"
            android:visibility="gone">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="评价图片:"
                android:textColor="@color/black"
                android:textSize="17sp" />
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:orientation="horizontal">
                <ImageView
                    android:id="@+id/iv_first"
                    android:layout_width="70dp"
                    android:layout_height="70dp"
                    android:layout_marginLeft="5dp"
                    android:scaleType="fitXY"
                    android:visibility="gone" />
                <ImageView
                    android:id="@+id/iv_second"
                    android:layout_width="70dp"
                    android:layout_height="70dp"
                    android:layout_marginLeft="5dp"
                    android:scaleType="fitXY"
                    android:visibility="gone" />
                <ImageView
                    android:id="@+id/iv_third"
                    android:layout_width="70dp"
                    android:layout_height="70dp"
                    android:layout_marginLeft="5dp"
                    android:scaleType="fitXY"
                    android:visibility="gone" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

3

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <include layout="@layout/title_evaluate" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5dp"
        android:orientation="vertical">
        <RatingBar
            android:id="@+id/rb_score"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:numStars="5"
            android:rating="3"
            android:stepSize="1" />
        <TextView
            android:id="@+id/tv_hint"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:gravity="left"
            android:text="请填写对**的评价:"
            android:textColor="@color/black"
            android:textSize="17sp" />
        <EditText
            android:id="@+id/et_comment"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="5dp"
            android:background="@drawable/editext_selector"
            android:gravity="left|top"
            android:hint="请填写评价文字"
            android:textColor="@color/black"
            android:textSize="17sp" />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="5dp"
            android:orientation="horizontal">
            <ImageView
                android:id="@+id/iv_first"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:layout_marginLeft="5dp"
                android:scaleType="fitXY"
                android:src="@drawable/add_pic"
                android:visibility="visible" />
            <ImageView
                android:id="@+id/iv_second"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:layout_marginLeft="5dp"
                android:scaleType="fitXY"
                android:src="@drawable/add_pic"
                android:visibility="gone" />
         it"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="提交评价"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </LinearLayout>
</LinearLayout>

创作不易 觉得有帮助请点赞关注收藏~~~

相关文章
|
JavaScript 前端开发 Android开发
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
579 13
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
12月前
|
Android开发 数据安全/隐私保护 开发者
Android自定义view之模仿登录界面文本输入框(华为云APP)
本文介绍了一款自定义输入框的实现,包含静态效果、hint值浮动动画及功能扩展。通过组合多个控件完成界面布局,使用TranslateAnimation与AlphaAnimation实现hint文字上下浮动效果,支持密码加密解密显示、去除键盘回车空格输入、光标定位等功能。代码基于Android平台,提供完整源码与attrs配置,方便复用与定制。希望对开发者有所帮助。
251 0
|
7月前
|
人工智能 小程序 搜索推荐
【一步步开发AI运动APP】十二、自定义扩展新运动项目2
本文介绍如何基于uni-app运动识别插件实现“双手并举”自定义扩展运动,涵盖动作拆解、姿态检测规则构建及运动分析器代码实现,助力开发者打造个性化AI运动APP。
|
8月前
|
存储 小程序 Java
热门小程序源码合集:微信抖音小程序源码支持PHP/Java/uni-app完整项目实践指南
小程序已成为企业获客与开发者创业的重要载体。本文详解PHP、Java、uni-app三大技术栈在电商、工具、服务类小程序中的源码应用,提供从开发到部署的全流程指南,并分享选型避坑与商业化落地策略,助力开发者高效构建稳定可扩展项目。
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
724 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
10月前
|
人工智能 小程序 前端开发
小程序、网站 vs. APP:成本差异究竟在哪里?技术栈如何决定项目上限?优雅草卓伊凡
小程序、网站 vs. APP:成本差异究竟在哪里?技术栈如何决定项目上限?优雅草卓伊凡
623 0
小程序、网站 vs. APP:成本差异究竟在哪里?技术栈如何决定项目上限?优雅草卓伊凡
|
10月前
|
存储 Android开发 数据安全/隐私保护
Thanox安卓系统增加工具下载,管理、阻止、限制后台每个APP运行情况
Thanox是一款Android系统管理工具,专注于权限、后台启动及运行管理。支持应用冻结、系统优化、UI自定义和模块管理,基于Xposed框架开发,安全可靠且开源免费,兼容Android 6.0及以上版本。
1251 4
|
数据采集 JSON 网络安全
移动端数据抓取:Android App的TLS流量解密方案
本文介绍了一种通过TLS流量解密技术抓取知乎App热榜数据的方法。利用Charles Proxy解密HTTPS流量,分析App与服务器通信内容;结合Python Requests库模拟请求,配置特定请求头以绕过反爬机制。同时使用代理IP隐藏真实IP地址,确保抓取稳定。最终成功提取热榜标题、内容简介、链接等信息,为分析热点话题和用户趋势提供数据支持。此方法也可应用于其他Android App的数据采集,但需注意选择可靠的代理服务。
593 11
移动端数据抓取:Android App的TLS流量解密方案
|
12月前
|
XML 搜索推荐 Android开发
Android改变进度条控件progressbar的样式(根据源码修改)
本文介绍了如何基于Android源码自定义ProgressBar样式。首先分析了系统源码中ProgressBar样式的定义,发现其依赖一张旋转图片实现动画效果。接着分两步指导开发者实现自定义:1) 模仿源码创建一个旋转动画XML文件(放置在drawable文件夹),修改图片为自定义样式;2) 在UI控件中通过`indeterminateDrawable`属性应用该动画。最终实现简单且个性化的ProgressBar效果,附带效果图展示。
685 2
|
NoSQL 应用服务中间件 PHP
布谷一对一直播源码android版环境配置流程及功能明细
部署需基于 CentOS 7.9 系统,硬盘不低于 40G,使用宝塔面板安装环境,包括 PHP 7.3(含 Redis、Fileinfo 扩展)、Nginx、MySQL 5.6、Redis 和最新 Composer。Swoole 扩展需按步骤配置。2021.08.05 后部署需将站点目录设为 public 并用 ThinkPHP 伪静态。开发环境建议 Windows 操作系统与最新 Android Studio,基础配置涉及 APP 名称修改、接口域名更换、包名调整及第三方登录分享(如 QQ、微信)的配置,同时需完成阿里云与腾讯云相关设置。

热门文章

最新文章