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>

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

相关文章
|
1月前
|
XML Java 数据库
安卓项目:app注册/登录界面设计
本文介绍了如何设计一个Android应用的注册/登录界面,包括布局文件的创建、登录和注册逻辑的实现,以及运行效果的展示。
140 0
安卓项目:app注册/登录界面设计
|
2月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android多线程编程的重要性及其实现方法,涵盖了基本概念、常见线程类型(如主线程、工作线程)以及多种多线程实现方式(如`Thread`、`HandlerThread`、`Executors`、Kotlin协程等)。通过合理的多线程管理,可大幅提升应用性能和用户体验。
123 15
一个Android App最少有几个线程?实现多线程的方式有哪些?
|
2月前
|
存储 开发工具 Android开发
使用.NET MAUI开发第一个安卓APP
【9月更文挑战第24天】使用.NET MAUI开发首个安卓APP需完成以下步骤:首先,安装Visual Studio 2022并勾选“.NET Multi-platform App UI development”工作负载;接着,安装Android SDK。然后,创建新项目时选择“.NET Multi-platform App (MAUI)”模板,并仅针对Android平台进行配置。了解项目结构,包括`.csproj`配置文件、`Properties`配置文件夹、平台特定代码及共享代码等。
163 2
|
2月前
|
XML Android开发 数据格式
🌐Android国际化与本地化全攻略!让你的App走遍全球无障碍!🌍
在全球化背景下,实现Android应用的国际化与本地化至关重要。本文以一款旅游指南App为例,详细介绍如何通过资源文件拆分与命名、适配布局与方向、处理日期时间及货币格式、考虑文化习俗等步骤,完成多语言支持和本地化调整。通过邀请用户测试并收集反馈,确保应用能无缝融入不同市场,提升用户体验与满意度。
103 3
|
2月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android应用开发中的多线程编程,涵盖基本概念、常见实现方式及最佳实践。主要内容包括主线程与工作线程的作用、多线程的多种实现方法(如 `Thread`、`HandlerThread`、`Executors` 和 Kotlin 协程),以及如何避免内存泄漏和合理使用线程池。通过有效的多线程管理,可以显著提升应用性能和用户体验。
69 10
|
1月前
|
安全 网络安全 Android开发
深度解析:利用Universal Links与Android App Links实现无缝网页至应用跳转的安全考量
【10月更文挑战第2天】在移动互联网时代,用户经常需要从网页无缝跳转到移动应用中。这种跳转不仅需要提供流畅的用户体验,还要确保安全性。本文将深入探讨如何利用Universal Links(仅限于iOS)和Android App Links技术实现这一目标,并分析其安全性。
224 0
|
2月前
|
XML 数据库 Android开发
10分钟手把手教你用Android手撸一个简易的个人记账App
该文章提供了使用Android Studio从零开始创建一个简单的个人记账应用的详细步骤,包括项目搭建、界面设计、数据库处理及各功能模块的实现方法。
|
3月前
|
API Android开发
Android P 性能优化:创建APP进程白名单,杀死白名单之外的进程
本文介绍了在Android P系统中通过创建应用进程白名单并杀死白名单之外的进程来优化性能的方法,包括设置权限、获取运行中的APP列表、配置白名单以及在应用启动时杀死非白名单进程的代码实现。
62 1
|
3月前
|
Android开发 iOS开发 C#
Xamarin:用C#打造跨平台移动应用的终极利器——从零开始构建你的第一个iOS与Android通用App,体验前所未有的高效与便捷开发之旅
【8月更文挑战第31天】Xamarin 是一个强大的框架,允许开发者使用单一的 C# 代码库构建高性能的原生移动应用,支持 iOS、Android 和 Windows 平台。作为微软的一部分,Xamarin 充分利用了 .NET 框架的强大功能,提供了丰富的 API 和工具集,简化了跨平台移动应用开发。本文通过一个简单的示例应用介绍了如何使用 Xamarin.Forms 快速创建跨平台应用,包括设置开发环境、定义用户界面和实现按钮点击事件处理逻辑。这个示例展示了 Xamarin.Forms 的基本功能,帮助开发者提高开发效率并实现一致的用户体验。
153 0
|
3月前
|
存储 XML Linux
深入理解操作系统:进程管理与调度策略探索安卓应用开发:从零开始构建你的第一个App
【8月更文挑战第28天】在数字世界里航行,操作系统是掌控一切的舵手。本文将带你领略操作系统的精妙设计,特别是进程管理和调度策略这两大核心领域。我们将从基础概念出发,逐步深入到复杂的实现机制,最后通过实际代码示例,揭示操作系统如何高效协调资源,确保多任务顺畅运行的秘密。准备好了吗?让我们启航,探索那些隐藏在日常电脑使用背后的奥秘。 【8月更文挑战第28天】在这个数字时代,拥有一款自己的移动应用程序不仅是技术的展示,也是实现创意和解决问题的一种方式。本文将引导初学者了解安卓开发的基础知识,通过一个简单的待办事项列表App项目,逐步介绍如何利用安卓开发工具和语言来创建、测试并发布一个基本的安卓应用