修改了界面中各个细节中的问题
This commit is contained in:
parent
ffb175ff78
commit
a6b56bceb1
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|
@ -64,6 +65,38 @@
|
||||||
android:name="com.example.livestreaming.FishPondActivity"
|
android:name="com.example.livestreaming.FishPondActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.example.livestreaming.VoiceMatchActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.example.livestreaming.HeartbeatSignalActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.example.livestreaming.OnlineDatingActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.example.livestreaming.FindGameActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.example.livestreaming.KTVTogetherActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.example.livestreaming.DrawGuessActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.example.livestreaming.PeaceEliteActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.example.livestreaming.TableGamesActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="com.example.livestreaming.ProfileActivity"
|
android:name="com.example.livestreaming.ProfileActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
|
||||||
657
android-app/app/src/main/assets/location_data.json
Normal file
657
android-app/app/src/main/assets/location_data.json
Normal file
|
|
@ -0,0 +1,657 @@
|
||||||
|
{
|
||||||
|
"provinces": [
|
||||||
|
{
|
||||||
|
"name": "北京",
|
||||||
|
"cities": [
|
||||||
|
{"name": "东城区"},
|
||||||
|
{"name": "西城区"},
|
||||||
|
{"name": "朝阳区"},
|
||||||
|
{"name": "丰台区"},
|
||||||
|
{"name": "石景山区"},
|
||||||
|
{"name": "海淀区"},
|
||||||
|
{"name": "门头沟区"},
|
||||||
|
{"name": "房山区"},
|
||||||
|
{"name": "通州区"},
|
||||||
|
{"name": "顺义区"},
|
||||||
|
{"name": "昌平区"},
|
||||||
|
{"name": "大兴区"},
|
||||||
|
{"name": "怀柔区"},
|
||||||
|
{"name": "平谷区"},
|
||||||
|
{"name": "密云区"},
|
||||||
|
{"name": "延庆区"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "上海",
|
||||||
|
"cities": [
|
||||||
|
{"name": "黄浦区"},
|
||||||
|
{"name": "徐汇区"},
|
||||||
|
{"name": "长宁区"},
|
||||||
|
{"name": "静安区"},
|
||||||
|
{"name": "普陀区"},
|
||||||
|
{"name": "虹口区"},
|
||||||
|
{"name": "杨浦区"},
|
||||||
|
{"name": "闵行区"},
|
||||||
|
{"name": "宝山区"},
|
||||||
|
{"name": "嘉定区"},
|
||||||
|
{"name": "浦东新区"},
|
||||||
|
{"name": "金山区"},
|
||||||
|
{"name": "松江区"},
|
||||||
|
{"name": "青浦区"},
|
||||||
|
{"name": "奉贤区"},
|
||||||
|
{"name": "崇明区"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "天津",
|
||||||
|
"cities": [
|
||||||
|
{"name": "和平区"},
|
||||||
|
{"name": "河东区"},
|
||||||
|
{"name": "河西区"},
|
||||||
|
{"name": "南开区"},
|
||||||
|
{"name": "河北区"},
|
||||||
|
{"name": "红桥区"},
|
||||||
|
{"name": "东丽区"},
|
||||||
|
{"name": "西青区"},
|
||||||
|
{"name": "津南区"},
|
||||||
|
{"name": "北辰区"},
|
||||||
|
{"name": "武清区"},
|
||||||
|
{"name": "宝坻区"},
|
||||||
|
{"name": "滨海新区"},
|
||||||
|
{"name": "宁河区"},
|
||||||
|
{"name": "静海区"},
|
||||||
|
{"name": "蓟州区"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "重庆",
|
||||||
|
"cities": [
|
||||||
|
{"name": "万州区"},
|
||||||
|
{"name": "涪陵区"},
|
||||||
|
{"name": "渝中区"},
|
||||||
|
{"name": "大渡口区"},
|
||||||
|
{"name": "江北区"},
|
||||||
|
{"name": "沙坪坝区"},
|
||||||
|
{"name": "九龙坡区"},
|
||||||
|
{"name": "南岸区"},
|
||||||
|
{"name": "北碚区"},
|
||||||
|
{"name": "綦江区"},
|
||||||
|
{"name": "大足区"},
|
||||||
|
{"name": "渝北区"},
|
||||||
|
{"name": "巴南区"},
|
||||||
|
{"name": "黔江区"},
|
||||||
|
{"name": "长寿区"},
|
||||||
|
{"name": "江津区"},
|
||||||
|
{"name": "合川区"},
|
||||||
|
{"name": "永川区"},
|
||||||
|
{"name": "南川区"},
|
||||||
|
{"name": "璧山区"},
|
||||||
|
{"name": "铜梁区"},
|
||||||
|
{"name": "潼南区"},
|
||||||
|
{"name": "荣昌区"},
|
||||||
|
{"name": "开州区"},
|
||||||
|
{"name": "梁平区"},
|
||||||
|
{"name": "武隆区"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "河北",
|
||||||
|
"cities": [
|
||||||
|
{"name": "石家庄"},
|
||||||
|
{"name": "唐山"},
|
||||||
|
{"name": "秦皇岛"},
|
||||||
|
{"name": "邯郸"},
|
||||||
|
{"name": "邢台"},
|
||||||
|
{"name": "保定"},
|
||||||
|
{"name": "张家口"},
|
||||||
|
{"name": "承德"},
|
||||||
|
{"name": "沧州"},
|
||||||
|
{"name": "廊坊"},
|
||||||
|
{"name": "衡水"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "山西",
|
||||||
|
"cities": [
|
||||||
|
{"name": "太原"},
|
||||||
|
{"name": "大同"},
|
||||||
|
{"name": "阳泉"},
|
||||||
|
{"name": "长治"},
|
||||||
|
{"name": "晋城"},
|
||||||
|
{"name": "朔州"},
|
||||||
|
{"name": "晋中"},
|
||||||
|
{"name": "运城"},
|
||||||
|
{"name": "忻州"},
|
||||||
|
{"name": "临汾"},
|
||||||
|
{"name": "吕梁"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "内蒙古",
|
||||||
|
"cities": [
|
||||||
|
{"name": "呼和浩特"},
|
||||||
|
{"name": "包头"},
|
||||||
|
{"name": "乌海"},
|
||||||
|
{"name": "赤峰"},
|
||||||
|
{"name": "通辽"},
|
||||||
|
{"name": "鄂尔多斯"},
|
||||||
|
{"name": "呼伦贝尔"},
|
||||||
|
{"name": "巴彦淖尔"},
|
||||||
|
{"name": "乌兰察布"},
|
||||||
|
{"name": "兴安盟"},
|
||||||
|
{"name": "锡林郭勒盟"},
|
||||||
|
{"name": "阿拉善盟"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "辽宁",
|
||||||
|
"cities": [
|
||||||
|
{"name": "沈阳"},
|
||||||
|
{"name": "大连"},
|
||||||
|
{"name": "鞍山"},
|
||||||
|
{"name": "抚顺"},
|
||||||
|
{"name": "本溪"},
|
||||||
|
{"name": "丹东"},
|
||||||
|
{"name": "锦州"},
|
||||||
|
{"name": "营口"},
|
||||||
|
{"name": "阜新"},
|
||||||
|
{"name": "辽阳"},
|
||||||
|
{"name": "盘锦"},
|
||||||
|
{"name": "铁岭"},
|
||||||
|
{"name": "朝阳"},
|
||||||
|
{"name": "葫芦岛"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "吉林",
|
||||||
|
"cities": [
|
||||||
|
{"name": "长春"},
|
||||||
|
{"name": "吉林"},
|
||||||
|
{"name": "四平"},
|
||||||
|
{"name": "辽源"},
|
||||||
|
{"name": "通化"},
|
||||||
|
{"name": "白山"},
|
||||||
|
{"name": "松原"},
|
||||||
|
{"name": "白城"},
|
||||||
|
{"name": "延边朝鲜族自治州"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "黑龙江",
|
||||||
|
"cities": [
|
||||||
|
{"name": "哈尔滨"},
|
||||||
|
{"name": "齐齐哈尔"},
|
||||||
|
{"name": "鸡西"},
|
||||||
|
{"name": "鹤岗"},
|
||||||
|
{"name": "双鸭山"},
|
||||||
|
{"name": "大庆"},
|
||||||
|
{"name": "伊春"},
|
||||||
|
{"name": "佳木斯"},
|
||||||
|
{"name": "七台河"},
|
||||||
|
{"name": "牡丹江"},
|
||||||
|
{"name": "黑河"},
|
||||||
|
{"name": "绥化"},
|
||||||
|
{"name": "大兴安岭"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "江苏",
|
||||||
|
"cities": [
|
||||||
|
{"name": "南京"},
|
||||||
|
{"name": "无锡"},
|
||||||
|
{"name": "徐州"},
|
||||||
|
{"name": "常州"},
|
||||||
|
{"name": "苏州"},
|
||||||
|
{"name": "南通"},
|
||||||
|
{"name": "连云港"},
|
||||||
|
{"name": "淮安"},
|
||||||
|
{"name": "盐城"},
|
||||||
|
{"name": "扬州"},
|
||||||
|
{"name": "镇江"},
|
||||||
|
{"name": "泰州"},
|
||||||
|
{"name": "宿迁"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "浙江",
|
||||||
|
"cities": [
|
||||||
|
{"name": "杭州"},
|
||||||
|
{"name": "宁波"},
|
||||||
|
{"name": "温州"},
|
||||||
|
{"name": "嘉兴"},
|
||||||
|
{"name": "湖州"},
|
||||||
|
{"name": "绍兴"},
|
||||||
|
{"name": "金华"},
|
||||||
|
{"name": "衢州"},
|
||||||
|
{"name": "舟山"},
|
||||||
|
{"name": "台州"},
|
||||||
|
{"name": "丽水"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "安徽",
|
||||||
|
"cities": [
|
||||||
|
{"name": "合肥"},
|
||||||
|
{"name": "芜湖"},
|
||||||
|
{"name": "蚌埠"},
|
||||||
|
{"name": "淮南"},
|
||||||
|
{"name": "马鞍山"},
|
||||||
|
{"name": "淮北"},
|
||||||
|
{"name": "铜陵"},
|
||||||
|
{"name": "安庆"},
|
||||||
|
{"name": "黄山"},
|
||||||
|
{"name": "滁州"},
|
||||||
|
{"name": "阜阳"},
|
||||||
|
{"name": "宿州"},
|
||||||
|
{"name": "六安"},
|
||||||
|
{"name": "亳州"},
|
||||||
|
{"name": "池州"},
|
||||||
|
{"name": "宣城"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "福建",
|
||||||
|
"cities": [
|
||||||
|
{"name": "福州"},
|
||||||
|
{"name": "厦门"},
|
||||||
|
{"name": "莆田"},
|
||||||
|
{"name": "三明"},
|
||||||
|
{"name": "泉州"},
|
||||||
|
{"name": "漳州"},
|
||||||
|
{"name": "南平"},
|
||||||
|
{"name": "龙岩"},
|
||||||
|
{"name": "宁德"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "江西",
|
||||||
|
"cities": [
|
||||||
|
{"name": "南昌"},
|
||||||
|
{"name": "景德镇"},
|
||||||
|
{"name": "萍乡"},
|
||||||
|
{"name": "九江"},
|
||||||
|
{"name": "新余"},
|
||||||
|
{"name": "鹰潭"},
|
||||||
|
{"name": "赣州"},
|
||||||
|
{"name": "吉安"},
|
||||||
|
{"name": "宜春"},
|
||||||
|
{"name": "抚州"},
|
||||||
|
{"name": "上饶"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "山东",
|
||||||
|
"cities": [
|
||||||
|
{"name": "济南"},
|
||||||
|
{"name": "青岛"},
|
||||||
|
{"name": "淄博"},
|
||||||
|
{"name": "枣庄"},
|
||||||
|
{"name": "东营"},
|
||||||
|
{"name": "烟台"},
|
||||||
|
{"name": "潍坊"},
|
||||||
|
{"name": "济宁"},
|
||||||
|
{"name": "泰安"},
|
||||||
|
{"name": "威海"},
|
||||||
|
{"name": "日照"},
|
||||||
|
{"name": "临沂"},
|
||||||
|
{"name": "德州"},
|
||||||
|
{"name": "聊城"},
|
||||||
|
{"name": "滨州"},
|
||||||
|
{"name": "菏泽"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "河南",
|
||||||
|
"cities": [
|
||||||
|
{"name": "郑州"},
|
||||||
|
{"name": "开封"},
|
||||||
|
{"name": "洛阳"},
|
||||||
|
{"name": "平顶山"},
|
||||||
|
{"name": "安阳"},
|
||||||
|
{"name": "鹤壁"},
|
||||||
|
{"name": "新乡"},
|
||||||
|
{"name": "焦作"},
|
||||||
|
{"name": "濮阳"},
|
||||||
|
{"name": "许昌"},
|
||||||
|
{"name": "漯河"},
|
||||||
|
{"name": "三门峡"},
|
||||||
|
{"name": "南阳"},
|
||||||
|
{"name": "商丘"},
|
||||||
|
{"name": "信阳"},
|
||||||
|
{"name": "周口"},
|
||||||
|
{"name": "驻马店"},
|
||||||
|
{"name": "济源"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "湖北",
|
||||||
|
"cities": [
|
||||||
|
{"name": "武汉"},
|
||||||
|
{"name": "黄石"},
|
||||||
|
{"name": "十堰"},
|
||||||
|
{"name": "宜昌"},
|
||||||
|
{"name": "襄阳"},
|
||||||
|
{"name": "鄂州"},
|
||||||
|
{"name": "荆门"},
|
||||||
|
{"name": "孝感"},
|
||||||
|
{"name": "荆州"},
|
||||||
|
{"name": "黄冈"},
|
||||||
|
{"name": "咸宁"},
|
||||||
|
{"name": "随州"},
|
||||||
|
{"name": "恩施"},
|
||||||
|
{"name": "仙桃"},
|
||||||
|
{"name": "潜江"},
|
||||||
|
{"name": "天门"},
|
||||||
|
{"name": "神农架"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "湖南",
|
||||||
|
"cities": [
|
||||||
|
{"name": "长沙"},
|
||||||
|
{"name": "株洲"},
|
||||||
|
{"name": "湘潭"},
|
||||||
|
{"name": "衡阳"},
|
||||||
|
{"name": "邵阳"},
|
||||||
|
{"name": "岳阳"},
|
||||||
|
{"name": "常德"},
|
||||||
|
{"name": "张家界"},
|
||||||
|
{"name": "益阳"},
|
||||||
|
{"name": "郴州"},
|
||||||
|
{"name": "永州"},
|
||||||
|
{"name": "怀化"},
|
||||||
|
{"name": "娄底"},
|
||||||
|
{"name": "湘西"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "广东",
|
||||||
|
"cities": [
|
||||||
|
{"name": "广州"},
|
||||||
|
{"name": "深圳"},
|
||||||
|
{"name": "珠海"},
|
||||||
|
{"name": "汕头"},
|
||||||
|
{"name": "佛山"},
|
||||||
|
{"name": "韶关"},
|
||||||
|
{"name": "湛江"},
|
||||||
|
{"name": "肇庆"},
|
||||||
|
{"name": "江门"},
|
||||||
|
{"name": "茂名"},
|
||||||
|
{"name": "惠州"},
|
||||||
|
{"name": "梅州"},
|
||||||
|
{"name": "汕尾"},
|
||||||
|
{"name": "河源"},
|
||||||
|
{"name": "阳江"},
|
||||||
|
{"name": "清远"},
|
||||||
|
{"name": "东莞"},
|
||||||
|
{"name": "中山"},
|
||||||
|
{"name": "潮州"},
|
||||||
|
{"name": "揭阳"},
|
||||||
|
{"name": "云浮"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "广西",
|
||||||
|
"cities": [
|
||||||
|
{"name": "南宁"},
|
||||||
|
{"name": "柳州"},
|
||||||
|
{"name": "桂林"},
|
||||||
|
{"name": "梧州"},
|
||||||
|
{"name": "北海"},
|
||||||
|
{"name": "防城港"},
|
||||||
|
{"name": "钦州"},
|
||||||
|
{"name": "贵港"},
|
||||||
|
{"name": "玉林"},
|
||||||
|
{"name": "百色"},
|
||||||
|
{"name": "贺州"},
|
||||||
|
{"name": "河池"},
|
||||||
|
{"name": "来宾"},
|
||||||
|
{"name": "崇左"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "海南",
|
||||||
|
"cities": [
|
||||||
|
{"name": "海口"},
|
||||||
|
{"name": "三亚"},
|
||||||
|
{"name": "三沙"},
|
||||||
|
{"name": "儋州"},
|
||||||
|
{"name": "五指山"},
|
||||||
|
{"name": "琼海"},
|
||||||
|
{"name": "文昌"},
|
||||||
|
{"name": "万宁"},
|
||||||
|
{"name": "东方"},
|
||||||
|
{"name": "定安"},
|
||||||
|
{"name": "屯昌"},
|
||||||
|
{"name": "澄迈"},
|
||||||
|
{"name": "临高"},
|
||||||
|
{"name": "白沙"},
|
||||||
|
{"name": "昌江"},
|
||||||
|
{"name": "乐东"},
|
||||||
|
{"name": "陵水"},
|
||||||
|
{"name": "保亭"},
|
||||||
|
{"name": "琼中"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "四川",
|
||||||
|
"cities": [
|
||||||
|
{"name": "成都"},
|
||||||
|
{"name": "自贡"},
|
||||||
|
{"name": "攀枝花"},
|
||||||
|
{"name": "泸州"},
|
||||||
|
{"name": "德阳"},
|
||||||
|
{"name": "绵阳"},
|
||||||
|
{"name": "广元"},
|
||||||
|
{"name": "遂宁"},
|
||||||
|
{"name": "内江"},
|
||||||
|
{"name": "乐山"},
|
||||||
|
{"name": "南充"},
|
||||||
|
{"name": "眉山"},
|
||||||
|
{"name": "宜宾"},
|
||||||
|
{"name": "广安"},
|
||||||
|
{"name": "达州"},
|
||||||
|
{"name": "雅安"},
|
||||||
|
{"name": "巴中"},
|
||||||
|
{"name": "资阳"},
|
||||||
|
{"name": "阿坝"},
|
||||||
|
{"name": "甘孜"},
|
||||||
|
{"name": "凉山"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "贵州",
|
||||||
|
"cities": [
|
||||||
|
{"name": "贵阳"},
|
||||||
|
{"name": "六盘水"},
|
||||||
|
{"name": "遵义"},
|
||||||
|
{"name": "安顺"},
|
||||||
|
{"name": "毕节"},
|
||||||
|
{"name": "铜仁"},
|
||||||
|
{"name": "黔西南"},
|
||||||
|
{"name": "黔东南"},
|
||||||
|
{"name": "黔南"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "云南",
|
||||||
|
"cities": [
|
||||||
|
{"name": "昆明"},
|
||||||
|
{"name": "曲靖"},
|
||||||
|
{"name": "玉溪"},
|
||||||
|
{"name": "保山"},
|
||||||
|
{"name": "昭通"},
|
||||||
|
{"name": "丽江"},
|
||||||
|
{"name": "普洱"},
|
||||||
|
{"name": "临沧"},
|
||||||
|
{"name": "楚雄"},
|
||||||
|
{"name": "红河"},
|
||||||
|
{"name": "文山"},
|
||||||
|
{"name": "西双版纳"},
|
||||||
|
{"name": "大理"},
|
||||||
|
{"name": "德宏"},
|
||||||
|
{"name": "怒江"},
|
||||||
|
{"name": "迪庆"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "西藏",
|
||||||
|
"cities": [
|
||||||
|
{"name": "拉萨"},
|
||||||
|
{"name": "日喀则"},
|
||||||
|
{"name": "昌都"},
|
||||||
|
{"name": "林芝"},
|
||||||
|
{"name": "山南"},
|
||||||
|
{"name": "那曲"},
|
||||||
|
{"name": "阿里"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "陕西",
|
||||||
|
"cities": [
|
||||||
|
{"name": "西安"},
|
||||||
|
{"name": "铜川"},
|
||||||
|
{"name": "宝鸡"},
|
||||||
|
{"name": "咸阳"},
|
||||||
|
{"name": "渭南"},
|
||||||
|
{"name": "延安"},
|
||||||
|
{"name": "汉中"},
|
||||||
|
{"name": "榆林"},
|
||||||
|
{"name": "安康"},
|
||||||
|
{"name": "商洛"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "甘肃",
|
||||||
|
"cities": [
|
||||||
|
{"name": "兰州"},
|
||||||
|
{"name": "嘉峪关"},
|
||||||
|
{"name": "金昌"},
|
||||||
|
{"name": "白银"},
|
||||||
|
{"name": "天水"},
|
||||||
|
{"name": "武威"},
|
||||||
|
{"name": "张掖"},
|
||||||
|
{"name": "平凉"},
|
||||||
|
{"name": "酒泉"},
|
||||||
|
{"name": "庆阳"},
|
||||||
|
{"name": "定西"},
|
||||||
|
{"name": "陇南"},
|
||||||
|
{"name": "临夏"},
|
||||||
|
{"name": "甘南"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "青海",
|
||||||
|
"cities": [
|
||||||
|
{"name": "西宁"},
|
||||||
|
{"name": "海东"},
|
||||||
|
{"name": "海北"},
|
||||||
|
{"name": "黄南"},
|
||||||
|
{"name": "海南"},
|
||||||
|
{"name": "果洛"},
|
||||||
|
{"name": "玉树"},
|
||||||
|
{"name": "海西"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "宁夏",
|
||||||
|
"cities": [
|
||||||
|
{"name": "银川"},
|
||||||
|
{"name": "石嘴山"},
|
||||||
|
{"name": "吴忠"},
|
||||||
|
{"name": "固原"},
|
||||||
|
{"name": "中卫"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "新疆",
|
||||||
|
"cities": [
|
||||||
|
{"name": "乌鲁木齐"},
|
||||||
|
{"name": "克拉玛依"},
|
||||||
|
{"name": "吐鲁番"},
|
||||||
|
{"name": "哈密"},
|
||||||
|
{"name": "昌吉"},
|
||||||
|
{"name": "博尔塔拉"},
|
||||||
|
{"name": "巴音郭楞"},
|
||||||
|
{"name": "阿克苏"},
|
||||||
|
{"name": "克孜勒苏"},
|
||||||
|
{"name": "喀什"},
|
||||||
|
{"name": "和田"},
|
||||||
|
{"name": "伊犁"},
|
||||||
|
{"name": "塔城"},
|
||||||
|
{"name": "阿勒泰"},
|
||||||
|
{"name": "石河子"},
|
||||||
|
{"name": "阿拉尔"},
|
||||||
|
{"name": "图木舒克"},
|
||||||
|
{"name": "五家渠"},
|
||||||
|
{"name": "北屯"},
|
||||||
|
{"name": "铁门关"},
|
||||||
|
{"name": "双河"},
|
||||||
|
{"name": "可克达拉"},
|
||||||
|
{"name": "昆玉"},
|
||||||
|
{"name": "胡杨河"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "台湾",
|
||||||
|
"cities": [
|
||||||
|
{"name": "台北"},
|
||||||
|
{"name": "新北"},
|
||||||
|
{"name": "桃园"},
|
||||||
|
{"name": "台中"},
|
||||||
|
{"name": "台南"},
|
||||||
|
{"name": "高雄"},
|
||||||
|
{"name": "基隆"},
|
||||||
|
{"name": "新竹"},
|
||||||
|
{"name": "嘉义"},
|
||||||
|
{"name": "宜兰"},
|
||||||
|
{"name": "苗栗"},
|
||||||
|
{"name": "彰化"},
|
||||||
|
{"name": "南投"},
|
||||||
|
{"name": "云林"},
|
||||||
|
{"name": "屏东"},
|
||||||
|
{"name": "台东"},
|
||||||
|
{"name": "花莲"},
|
||||||
|
{"name": "澎湖"},
|
||||||
|
{"name": "金门"},
|
||||||
|
{"name": "连江"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "香港",
|
||||||
|
"cities": [
|
||||||
|
{"name": "中西区"},
|
||||||
|
{"name": "湾仔区"},
|
||||||
|
{"name": "东区"},
|
||||||
|
{"name": "南区"},
|
||||||
|
{"name": "深水埗区"},
|
||||||
|
{"name": "油尖旺区"},
|
||||||
|
{"name": "九龙城区"},
|
||||||
|
{"name": "黄大仙区"},
|
||||||
|
{"name": "观塘区"},
|
||||||
|
{"name": "荃湾区"},
|
||||||
|
{"name": "屯门区"},
|
||||||
|
{"name": "元朗区"},
|
||||||
|
{"name": "北区"},
|
||||||
|
{"name": "大埔区"},
|
||||||
|
{"name": "沙田区"},
|
||||||
|
{"name": "西贡区"},
|
||||||
|
{"name": "葵青区"},
|
||||||
|
{"name": "离岛区"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "澳门",
|
||||||
|
"cities": [
|
||||||
|
{"name": "花地玛堂区"},
|
||||||
|
{"name": "圣安多尼堂区"},
|
||||||
|
{"name": "望德堂区"},
|
||||||
|
{"name": "大堂区"},
|
||||||
|
{"name": "风顺堂区"},
|
||||||
|
{"name": "嘉模堂区"},
|
||||||
|
{"name": "路凼填海区"},
|
||||||
|
{"name": "圣方济各堂区"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,162 @@
|
||||||
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||||
|
|
||||||
|
public class AvatarViewerDialog extends Dialog {
|
||||||
|
|
||||||
|
private ImageView avatarImageView;
|
||||||
|
private Uri avatarUri;
|
||||||
|
private Integer avatarResId;
|
||||||
|
private Drawable avatarDrawable;
|
||||||
|
private Context activityContext;
|
||||||
|
|
||||||
|
public AvatarViewerDialog(@NonNull Context context) {
|
||||||
|
super(context, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
|
||||||
|
this.activityContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AvatarViewerDialog create(Context context) {
|
||||||
|
return new AvatarViewerDialog(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AvatarViewerDialog setAvatarUri(Uri uri) {
|
||||||
|
this.avatarUri = uri;
|
||||||
|
this.avatarResId = null;
|
||||||
|
this.avatarDrawable = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AvatarViewerDialog setAvatarResId(int resId) {
|
||||||
|
this.avatarResId = resId;
|
||||||
|
this.avatarUri = null;
|
||||||
|
this.avatarDrawable = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AvatarViewerDialog setAvatarDrawable(Drawable drawable) {
|
||||||
|
this.avatarDrawable = drawable;
|
||||||
|
this.avatarUri = null;
|
||||||
|
this.avatarResId = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AvatarViewerDialog setAvatarFromImageView(ImageView imageView) {
|
||||||
|
if (imageView == null) return this;
|
||||||
|
|
||||||
|
// 优先从ImageView的Drawable获取
|
||||||
|
Drawable drawable = imageView.getDrawable();
|
||||||
|
if (drawable != null) {
|
||||||
|
return setAvatarDrawable(drawable);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果Drawable为空,尝试从Tag获取URI或资源ID
|
||||||
|
Object tag = imageView.getTag();
|
||||||
|
if (tag instanceof Uri) {
|
||||||
|
return setAvatarUri((Uri) tag);
|
||||||
|
} else if (tag instanceof Integer) {
|
||||||
|
return setAvatarResId((Integer) tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
|
setContentView(R.layout.dialog_avatar_viewer);
|
||||||
|
|
||||||
|
Window window = getWindow();
|
||||||
|
if (window != null) {
|
||||||
|
WindowManager.LayoutParams params = window.getAttributes();
|
||||||
|
params.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||||
|
params.height = WindowManager.LayoutParams.MATCH_PARENT;
|
||||||
|
window.setAttributes(params);
|
||||||
|
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
window.setBackgroundDrawableResource(android.R.color.black);
|
||||||
|
}
|
||||||
|
|
||||||
|
avatarImageView = findViewById(R.id.avatarImageView);
|
||||||
|
|
||||||
|
if (avatarImageView == null) {
|
||||||
|
dismiss();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击任意位置关闭
|
||||||
|
View rootLayout = findViewById(R.id.rootLayout);
|
||||||
|
if (rootLayout != null) {
|
||||||
|
rootLayout.setOnClickListener(v -> dismiss());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 也允许点击ImageView关闭
|
||||||
|
avatarImageView.setOnClickListener(v -> dismiss());
|
||||||
|
|
||||||
|
loadAvatar();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadAvatar() {
|
||||||
|
if (avatarImageView == null) return;
|
||||||
|
|
||||||
|
// 使用Activity的Context而不是Dialog的Context,确保Glide能正常工作
|
||||||
|
Context context = activityContext;
|
||||||
|
if (context == null) {
|
||||||
|
context = getContext();
|
||||||
|
}
|
||||||
|
if (context == null) {
|
||||||
|
avatarImageView.setImageResource(R.drawable.ic_account_circle_24);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (avatarUri != null) {
|
||||||
|
Glide.with(context)
|
||||||
|
.load(avatarUri)
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
|
.placeholder(R.drawable.ic_account_circle_24)
|
||||||
|
.error(R.drawable.ic_account_circle_24)
|
||||||
|
.into(avatarImageView);
|
||||||
|
} else if (avatarResId != null && avatarResId != 0) {
|
||||||
|
Glide.with(context)
|
||||||
|
.load(avatarResId)
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
|
.placeholder(R.drawable.ic_account_circle_24)
|
||||||
|
.error(R.drawable.ic_account_circle_24)
|
||||||
|
.into(avatarImageView);
|
||||||
|
} else if (avatarDrawable != null) {
|
||||||
|
// 直接设置Drawable,但如果是Glide的Drawable,可能需要特殊处理
|
||||||
|
try {
|
||||||
|
avatarImageView.setImageDrawable(avatarDrawable);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 如果设置Drawable失败,尝试使用Glide加载
|
||||||
|
// 对于Glide加载的Drawable,我们需要重新加载原始资源
|
||||||
|
avatarImageView.setImageResource(R.drawable.ic_account_circle_24);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
avatarImageView.setImageResource(R.drawable.ic_account_circle_24);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 如果Glide加载失败,直接使用setImageResource
|
||||||
|
try {
|
||||||
|
avatarImageView.setImageResource(R.drawable.ic_account_circle_24);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
// 最后的fallback
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -33,6 +33,10 @@ public class ConversationActivity extends AppCompatActivity {
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String EXTRA_UNREAD_COUNT = "extra_unread_count";
|
||||||
|
|
||||||
|
private int initialUnreadCount = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
@ -42,10 +46,24 @@ public class ConversationActivity extends AppCompatActivity {
|
||||||
String title = getIntent() != null ? getIntent().getStringExtra(EXTRA_CONVERSATION_TITLE) : null;
|
String title = getIntent() != null ? getIntent().getStringExtra(EXTRA_CONVERSATION_TITLE) : null;
|
||||||
binding.titleText.setText(title != null ? title : "会话");
|
binding.titleText.setText(title != null ? title : "会话");
|
||||||
|
|
||||||
|
// 获取该会话的初始未读数量
|
||||||
|
initialUnreadCount = getIntent() != null ? getIntent().getIntExtra(EXTRA_UNREAD_COUNT, 0) : 0;
|
||||||
|
|
||||||
binding.backButton.setOnClickListener(v -> finish());
|
binding.backButton.setOnClickListener(v -> finish());
|
||||||
|
|
||||||
setupMessages();
|
setupMessages();
|
||||||
setupInput();
|
setupInput();
|
||||||
|
|
||||||
|
// 用户进入会话时,标记该会话的消息为已读,减少未读数量
|
||||||
|
if (initialUnreadCount > 0) {
|
||||||
|
UnreadMessageManager.decrementUnreadCount(this, initialUnreadCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
// 当用户离开会话时,更新总未读数量(如果会话未读数量已减少)
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupMessages() {
|
private void setupMessages() {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
package com.example.livestreaming;
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.graphics.Outline;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewOutlineProvider;
|
||||||
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
@ -10,6 +15,8 @@ import androidx.recyclerview.widget.DiffUtil;
|
||||||
import androidx.recyclerview.widget.ListAdapter;
|
import androidx.recyclerview.widget.ListAdapter;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
@ -56,15 +63,35 @@ public class ConversationMessagesAdapter extends ListAdapter<ChatMessage, Recycl
|
||||||
}
|
}
|
||||||
|
|
||||||
static class IncomingVH extends RecyclerView.ViewHolder {
|
static class IncomingVH extends RecyclerView.ViewHolder {
|
||||||
|
private final ImageView avatarView;
|
||||||
private final TextView nameText;
|
private final TextView nameText;
|
||||||
private final TextView msgText;
|
private final TextView msgText;
|
||||||
private final TextView timeText;
|
private final TextView timeText;
|
||||||
|
|
||||||
IncomingVH(@NonNull View itemView) {
|
IncomingVH(@NonNull View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
|
avatarView = itemView.findViewById(R.id.avatarView);
|
||||||
nameText = itemView.findViewById(R.id.nameText);
|
nameText = itemView.findViewById(R.id.nameText);
|
||||||
msgText = itemView.findViewById(R.id.messageText);
|
msgText = itemView.findViewById(R.id.messageText);
|
||||||
timeText = itemView.findViewById(R.id.timeText);
|
timeText = itemView.findViewById(R.id.timeText);
|
||||||
|
setupAvatarOutline();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupAvatarOutline() {
|
||||||
|
if (avatarView == null) return;
|
||||||
|
// 设置圆形裁剪,确保在模拟器上也能正常工作
|
||||||
|
// 使用post确保在View布局完成后再设置outline
|
||||||
|
avatarView.post(() -> {
|
||||||
|
if (avatarView.getWidth() > 0 && avatarView.getHeight() > 0) {
|
||||||
|
avatarView.setOutlineProvider(new ViewOutlineProvider() {
|
||||||
|
@Override
|
||||||
|
public void getOutline(View view, Outline outline) {
|
||||||
|
outline.setOval(0, 0, view.getWidth(), view.getHeight());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
avatarView.setClipToOutline(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind(ChatMessage message) {
|
void bind(ChatMessage message) {
|
||||||
|
|
@ -72,23 +99,114 @@ public class ConversationMessagesAdapter extends ListAdapter<ChatMessage, Recycl
|
||||||
nameText.setText(message.getUsername() != null ? message.getUsername() : "");
|
nameText.setText(message.getUsername() != null ? message.getUsername() : "");
|
||||||
msgText.setText(message.getMessage() != null ? message.getMessage() : "");
|
msgText.setText(message.getMessage() != null ? message.getMessage() : "");
|
||||||
timeText.setText(TIME_FORMAT.format(new Date(message.getTimestamp())));
|
timeText.setText(TIME_FORMAT.format(new Date(message.getTimestamp())));
|
||||||
|
|
||||||
|
// 确保头像圆形裁剪设置正确
|
||||||
|
setupAvatarOutline();
|
||||||
|
// 加载对方头像(可以根据用户名或其他信息加载)
|
||||||
|
loadAvatar(message.getUsername());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadAvatar(String username) {
|
||||||
|
if (avatarView == null) return;
|
||||||
|
|
||||||
|
// 这里可以根据用户名加载对应的头像
|
||||||
|
// 暂时使用默认头像,后续可以根据实际需求从服务器或本地加载
|
||||||
|
try {
|
||||||
|
// 可以根据username从SharedPreferences或其他地方加载头像
|
||||||
|
// 这里先使用默认头像,使用Glide确保圆形裁剪
|
||||||
|
Glide.with(avatarView)
|
||||||
|
.load(R.drawable.ic_account_circle_24)
|
||||||
|
.circleCrop()
|
||||||
|
.into(avatarView);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Glide.with(avatarView)
|
||||||
|
.load(R.drawable.ic_account_circle_24)
|
||||||
|
.circleCrop()
|
||||||
|
.into(avatarView);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class OutgoingVH extends RecyclerView.ViewHolder {
|
static class OutgoingVH extends RecyclerView.ViewHolder {
|
||||||
|
private final ImageView avatarView;
|
||||||
private final TextView msgText;
|
private final TextView msgText;
|
||||||
private final TextView timeText;
|
private final TextView timeText;
|
||||||
|
|
||||||
OutgoingVH(@NonNull View itemView) {
|
OutgoingVH(@NonNull View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
|
avatarView = itemView.findViewById(R.id.avatarView);
|
||||||
msgText = itemView.findViewById(R.id.messageText);
|
msgText = itemView.findViewById(R.id.messageText);
|
||||||
timeText = itemView.findViewById(R.id.timeText);
|
timeText = itemView.findViewById(R.id.timeText);
|
||||||
|
setupAvatarOutline();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupAvatarOutline() {
|
||||||
|
if (avatarView == null) return;
|
||||||
|
// 设置圆形裁剪,确保在模拟器上也能正常工作
|
||||||
|
// 使用post确保在View布局完成后再设置outline
|
||||||
|
avatarView.post(() -> {
|
||||||
|
if (avatarView.getWidth() > 0 && avatarView.getHeight() > 0) {
|
||||||
|
avatarView.setOutlineProvider(new ViewOutlineProvider() {
|
||||||
|
@Override
|
||||||
|
public void getOutline(View view, Outline outline) {
|
||||||
|
outline.setOval(0, 0, view.getWidth(), view.getHeight());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
avatarView.setClipToOutline(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind(ChatMessage message) {
|
void bind(ChatMessage message) {
|
||||||
if (message == null) return;
|
if (message == null) return;
|
||||||
msgText.setText(message.getMessage() != null ? message.getMessage() : "");
|
msgText.setText(message.getMessage() != null ? message.getMessage() : "");
|
||||||
timeText.setText(TIME_FORMAT.format(new Date(message.getTimestamp())));
|
timeText.setText(TIME_FORMAT.format(new Date(message.getTimestamp())));
|
||||||
|
|
||||||
|
// 确保头像圆形裁剪设置正确
|
||||||
|
setupAvatarOutline();
|
||||||
|
// 加载用户头像
|
||||||
|
loadAvatar();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadAvatar() {
|
||||||
|
if (avatarView == null) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
String avatarUri = avatarView.getContext()
|
||||||
|
.getSharedPreferences("profile_prefs", android.content.Context.MODE_PRIVATE)
|
||||||
|
.getString("profile_avatar_uri", null);
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(avatarUri)) {
|
||||||
|
Glide.with(avatarView)
|
||||||
|
.load(Uri.parse(avatarUri))
|
||||||
|
.circleCrop()
|
||||||
|
.error(R.drawable.ic_account_circle_24)
|
||||||
|
.into(avatarView);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int avatarRes = avatarView.getContext()
|
||||||
|
.getSharedPreferences("profile_prefs", android.content.Context.MODE_PRIVATE)
|
||||||
|
.getInt("profile_avatar_res", 0);
|
||||||
|
|
||||||
|
if (avatarRes != 0) {
|
||||||
|
Glide.with(avatarView)
|
||||||
|
.load(avatarRes)
|
||||||
|
.circleCrop()
|
||||||
|
.error(R.drawable.ic_account_circle_24)
|
||||||
|
.into(avatarView);
|
||||||
|
} else {
|
||||||
|
Glide.with(avatarView)
|
||||||
|
.load(R.drawable.ic_account_circle_24)
|
||||||
|
.circleCrop()
|
||||||
|
.into(avatarView);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Glide.with(avatarView)
|
||||||
|
.load(R.drawable.ic_account_circle_24)
|
||||||
|
.circleCrop()
|
||||||
|
.into(avatarView);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,19 @@
|
||||||
package com.example.livestreaming;
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.graphics.Outline;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewOutlineProvider;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.DiffUtil;
|
import androidx.recyclerview.widget.DiffUtil;
|
||||||
import androidx.recyclerview.widget.ListAdapter;
|
import androidx.recyclerview.widget.ListAdapter;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
import com.example.livestreaming.databinding.ItemConversationBinding;
|
import com.example.livestreaming.databinding.ItemConversationBinding;
|
||||||
|
|
||||||
public class ConversationsAdapter extends ListAdapter<ConversationItem, ConversationsAdapter.VH> {
|
public class ConversationsAdapter extends ListAdapter<ConversationItem, ConversationsAdapter.VH> {
|
||||||
|
|
@ -66,11 +71,56 @@ public class ConversationsAdapter extends ListAdapter<ConversationItem, Conversa
|
||||||
binding.muteIcon.setVisibility(View.GONE);
|
binding.muteIcon.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载头像
|
||||||
|
loadAvatar(item);
|
||||||
|
|
||||||
binding.getRoot().setOnClickListener(v -> {
|
binding.getRoot().setOnClickListener(v -> {
|
||||||
if (item == null) return;
|
if (item == null) return;
|
||||||
if (onConversationClickListener != null) onConversationClickListener.onConversationClick(item);
|
if (onConversationClickListener != null) onConversationClickListener.onConversationClick(item);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadAvatar(ConversationItem item) {
|
||||||
|
if (binding.avatar == null) return;
|
||||||
|
|
||||||
|
// 设置圆形裁剪
|
||||||
|
setupAvatarOutline();
|
||||||
|
|
||||||
|
// 根据会话ID或标题加载对应的头像
|
||||||
|
// 这里可以根据实际需求从服务器或本地加载
|
||||||
|
// 暂时使用默认头像,或者根据会话类型加载不同头像
|
||||||
|
try {
|
||||||
|
String conversationId = item != null ? item.getId() : null;
|
||||||
|
|
||||||
|
// 可以根据conversationId从SharedPreferences或其他地方加载头像
|
||||||
|
// 这里先使用默认头像,使用Glide确保圆形裁剪
|
||||||
|
Glide.with(binding.avatar)
|
||||||
|
.load(R.drawable.ic_account_circle_24)
|
||||||
|
.circleCrop()
|
||||||
|
.into(binding.avatar);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Glide.with(binding.avatar)
|
||||||
|
.load(R.drawable.ic_account_circle_24)
|
||||||
|
.circleCrop()
|
||||||
|
.into(binding.avatar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupAvatarOutline() {
|
||||||
|
if (binding.avatar == null) return;
|
||||||
|
// 设置圆形裁剪,确保在模拟器上也能正常工作
|
||||||
|
binding.avatar.post(() -> {
|
||||||
|
if (binding.avatar.getWidth() > 0 && binding.avatar.getHeight() > 0) {
|
||||||
|
binding.avatar.setOutlineProvider(new ViewOutlineProvider() {
|
||||||
|
@Override
|
||||||
|
public void getOutline(View view, Outline outline) {
|
||||||
|
outline.setOval(0, 0, view.getWidth(), view.getHeight());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
binding.avatar.setClipToOutline(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final DiffUtil.ItemCallback<ConversationItem> DIFF = new DiffUtil.ItemCallback<ConversationItem>() {
|
private static final DiffUtil.ItemCallback<ConversationItem> DIFF = new DiffUtil.ItemCallback<ConversationItem>() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.example.livestreaming.databinding.ActivityDrawGuessBinding;
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
|
public class DrawGuessActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private ActivityDrawGuessBinding binding;
|
||||||
|
|
||||||
|
public static void start(Context context) {
|
||||||
|
Intent intent = new Intent(context, DrawGuessActivity.class);
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
binding = ActivityDrawGuessBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
|
setupUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupUI() {
|
||||||
|
binding.backButton.setOnClickListener(v -> finish());
|
||||||
|
|
||||||
|
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
||||||
|
bottomNavigation.setSelectedItemId(R.id.nav_friends);
|
||||||
|
bottomNavigation.setOnItemSelectedListener(item -> {
|
||||||
|
int id = item.getItemId();
|
||||||
|
if (id == R.id.nav_home) {
|
||||||
|
startActivity(new Intent(this, MainActivity.class));
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_wish_tree) {
|
||||||
|
WishTreeActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_messages) {
|
||||||
|
MessagesActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_profile) {
|
||||||
|
ProfileActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -4,25 +4,41 @@ import android.Manifest;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.AutoCompleteTextView;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.content.FileProvider;
|
import androidx.core.content.FileProvider;
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.example.livestreaming.databinding.ActivityEditProfileBinding;
|
import com.example.livestreaming.databinding.ActivityEditProfileBinding;
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||||
|
import android.widget.NumberPicker;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class EditProfileActivity extends AppCompatActivity {
|
public class EditProfileActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
|
@ -84,9 +100,41 @@ public class EditProfileActivity extends AppCompatActivity {
|
||||||
binding.cancelButton.setOnClickListener(v -> finish());
|
binding.cancelButton.setOnClickListener(v -> finish());
|
||||||
|
|
||||||
loadFromPrefs();
|
loadFromPrefs();
|
||||||
|
setupGenderDropdown();
|
||||||
|
setupLocationDropdown();
|
||||||
|
setupBirthdayPicker();
|
||||||
|
|
||||||
binding.avatarRow.setOnClickListener(v -> showAvatarBottomSheet());
|
binding.avatarRow.setOnClickListener(v -> showAvatarBottomSheet());
|
||||||
|
|
||||||
|
// 头像预览点击放大
|
||||||
|
binding.avatarPreview.setOnClickListener(v -> {
|
||||||
|
AvatarViewerDialog dialog = AvatarViewerDialog.create(this);
|
||||||
|
|
||||||
|
// 优先使用selectedAvatarUri(当前选择但未保存的头像)
|
||||||
|
if (selectedAvatarUri != null) {
|
||||||
|
dialog.setAvatarUri(selectedAvatarUri);
|
||||||
|
} else {
|
||||||
|
// 如果没有选择新头像,从SharedPreferences读取
|
||||||
|
String avatarUri = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_AVATAR_URI, null);
|
||||||
|
int avatarRes = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getInt(KEY_AVATAR_RES, 0);
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(avatarUri)) {
|
||||||
|
dialog.setAvatarUri(Uri.parse(avatarUri));
|
||||||
|
} else if (avatarRes != 0) {
|
||||||
|
dialog.setAvatarResId(avatarRes);
|
||||||
|
} else {
|
||||||
|
// 如果都没有,尝试从ImageView获取Drawable
|
||||||
|
Drawable drawable = binding.avatarPreview.getDrawable();
|
||||||
|
if (drawable != null) {
|
||||||
|
dialog.setAvatarDrawable(drawable);
|
||||||
|
} else {
|
||||||
|
dialog.setAvatarResId(R.drawable.ic_account_circle_24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dialog.show();
|
||||||
|
});
|
||||||
|
|
||||||
binding.saveButton.setOnClickListener(v -> {
|
binding.saveButton.setOnClickListener(v -> {
|
||||||
String name = binding.inputName.getText() != null ? binding.inputName.getText().toString().trim() : "";
|
String name = binding.inputName.getText() != null ? binding.inputName.getText().toString().trim() : "";
|
||||||
String bio = binding.inputBio.getText() != null ? binding.inputBio.getText().toString().trim() : "";
|
String bio = binding.inputBio.getText() != null ? binding.inputBio.getText().toString().trim() : "";
|
||||||
|
|
@ -121,9 +169,12 @@ public class EditProfileActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 生日已经在日期选择器中实时保存,这里只需要确保同步
|
||||||
|
// 如果输入框为空,则清除
|
||||||
if (TextUtils.isEmpty(birthday)) {
|
if (TextUtils.isEmpty(birthday)) {
|
||||||
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().remove(KEY_BIRTHDAY).apply();
|
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().remove(KEY_BIRTHDAY).apply();
|
||||||
} else {
|
} else {
|
||||||
|
// 确保使用输入框中的最新值
|
||||||
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putString(KEY_BIRTHDAY, birthday).apply();
|
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putString(KEY_BIRTHDAY, birthday).apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,6 +190,8 @@ public class EditProfileActivity extends AppCompatActivity {
|
||||||
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putString(KEY_LOCATION, location).apply();
|
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putString(KEY_LOCATION, location).apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 设置结果,通知ProfileActivity需要刷新
|
||||||
|
setResult(RESULT_OK);
|
||||||
finish();
|
finish();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -200,6 +253,11 @@ public class EditProfileActivity extends AppCompatActivity {
|
||||||
if (!TextUtils.isEmpty(avatarUri)) {
|
if (!TextUtils.isEmpty(avatarUri)) {
|
||||||
selectedAvatarUri = Uri.parse(avatarUri);
|
selectedAvatarUri = Uri.parse(avatarUri);
|
||||||
Glide.with(this).load(selectedAvatarUri).circleCrop().into(binding.avatarPreview);
|
Glide.with(this).load(selectedAvatarUri).circleCrop().into(binding.avatarPreview);
|
||||||
|
} else {
|
||||||
|
int avatarRes = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getInt(KEY_AVATAR_RES, 0);
|
||||||
|
if (avatarRes != 0) {
|
||||||
|
Glide.with(this).load(avatarRes).circleCrop().into(binding.avatarPreview);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,4 +308,254 @@ public class EditProfileActivity extends AppCompatActivity {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupGenderDropdown() {
|
||||||
|
String[] genders = {"男", "女", "保密"};
|
||||||
|
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, genders);
|
||||||
|
|
||||||
|
binding.inputGender.setOnClickListener(v -> {
|
||||||
|
android.widget.PopupMenu popupMenu = new android.widget.PopupMenu(this, binding.inputGender);
|
||||||
|
for (int i = 0; i < genders.length; i++) {
|
||||||
|
popupMenu.getMenu().add(android.view.Menu.NONE, i, i, genders[i]);
|
||||||
}
|
}
|
||||||
|
popupMenu.setOnMenuItemClickListener(item -> {
|
||||||
|
String selectedGender = genders[item.getItemId()];
|
||||||
|
binding.inputGender.setText(selectedGender);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
popupMenu.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupLocationDropdown() {
|
||||||
|
binding.inputLocation.setOnClickListener(v -> showLocationPicker());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showLocationPicker() {
|
||||||
|
BottomSheetDialog dialog = new BottomSheetDialog(this);
|
||||||
|
View view = LayoutInflater.from(this).inflate(R.layout.bottom_sheet_location_picker_spinner, null);
|
||||||
|
dialog.setContentView(view);
|
||||||
|
|
||||||
|
Spinner provinceSpinner = view.findViewById(R.id.provinceSpinner);
|
||||||
|
Spinner citySpinner = view.findViewById(R.id.citySpinner);
|
||||||
|
TextView confirmButton = view.findViewById(R.id.confirmButton);
|
||||||
|
TextView cancelButton = view.findViewById(R.id.cancelButton);
|
||||||
|
|
||||||
|
// 加载地址数据
|
||||||
|
LocationDataManager locationManager = LocationDataManager.getInstance();
|
||||||
|
locationManager.loadData(this);
|
||||||
|
|
||||||
|
// 解析当前地址
|
||||||
|
String currentLocation = binding.inputLocation.getText() != null ? binding.inputLocation.getText().toString() : "";
|
||||||
|
String[] parsed = locationManager.parseLocation(currentLocation);
|
||||||
|
String currentProvince = parsed[0];
|
||||||
|
String currentCity = parsed[1];
|
||||||
|
|
||||||
|
// 初始化省份Spinner
|
||||||
|
List<String> provinceNames = locationManager.getProvinceNames();
|
||||||
|
ArrayAdapter<String> provinceAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, provinceNames);
|
||||||
|
provinceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
provinceSpinner.setAdapter(provinceAdapter);
|
||||||
|
|
||||||
|
// 设置当前选中的省份
|
||||||
|
if (!TextUtils.isEmpty(currentProvince)) {
|
||||||
|
int provinceIndex = locationManager.findProvinceIndex(currentProvince);
|
||||||
|
if (provinceIndex >= 0 && provinceIndex < provinceNames.size()) {
|
||||||
|
provinceSpinner.setSelection(provinceIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化城市Spinner
|
||||||
|
final String[] selectedProvince = {currentProvince};
|
||||||
|
final String[] selectedCity = {currentCity};
|
||||||
|
|
||||||
|
updateCitySpinner(citySpinner, locationManager, selectedProvince[0], selectedCity[0]);
|
||||||
|
|
||||||
|
// 省份选择监听
|
||||||
|
provinceSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
selectedProvince[0] = provinceNames.get(position);
|
||||||
|
selectedCity[0] = "";
|
||||||
|
updateCitySpinner(citySpinner, locationManager, selectedProvince[0], "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 城市选择监听
|
||||||
|
citySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
List<String> cityNames = locationManager.getCityNames(selectedProvince[0]);
|
||||||
|
if (position >= 0 && position < cityNames.size()) {
|
||||||
|
selectedCity[0] = cityNames.get(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
confirmButton.setOnClickListener(v -> {
|
||||||
|
String location = locationManager.formatLocation(selectedProvince[0], selectedCity[0]);
|
||||||
|
binding.inputLocation.setText(location);
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
|
||||||
|
cancelButton.setOnClickListener(v -> dialog.dismiss());
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateCitySpinner(Spinner citySpinner, LocationDataManager locationManager, String province, String selectedCity) {
|
||||||
|
List<String> cityNames = locationManager.getCityNames(province);
|
||||||
|
ArrayAdapter<String> cityAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, cityNames);
|
||||||
|
cityAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
citySpinner.setAdapter(cityAdapter);
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(selectedCity) && cityNames.contains(selectedCity)) {
|
||||||
|
int cityIndex = locationManager.findCityIndex(province, selectedCity);
|
||||||
|
if (cityIndex >= 0 && cityIndex < cityNames.size()) {
|
||||||
|
citySpinner.setSelection(cityIndex);
|
||||||
|
}
|
||||||
|
} else if (!cityNames.isEmpty()) {
|
||||||
|
citySpinner.setSelection(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupBirthdayPicker() {
|
||||||
|
binding.inputBirthday.setOnClickListener(v -> showDatePicker());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDatePicker() {
|
||||||
|
BottomSheetDialog dialog = new BottomSheetDialog(this);
|
||||||
|
View view = LayoutInflater.from(this).inflate(R.layout.bottom_sheet_date_picker, null);
|
||||||
|
dialog.setContentView(view);
|
||||||
|
|
||||||
|
NumberPicker yearPicker = view.findViewById(R.id.yearPicker);
|
||||||
|
NumberPicker monthPicker = view.findViewById(R.id.monthPicker);
|
||||||
|
NumberPicker dayPicker = view.findViewById(R.id.dayPicker);
|
||||||
|
TextView confirmButton = view.findViewById(R.id.confirmButton);
|
||||||
|
TextView cancelButton = view.findViewById(R.id.cancelButton);
|
||||||
|
|
||||||
|
// 获取当前日期
|
||||||
|
Calendar today = Calendar.getInstance();
|
||||||
|
int currentYear = today.get(Calendar.YEAR);
|
||||||
|
int currentMonth = today.get(Calendar.MONTH) + 1; // Calendar.MONTH 从0开始
|
||||||
|
int currentDay = today.get(Calendar.DAY_OF_MONTH);
|
||||||
|
|
||||||
|
// 解析当前生日
|
||||||
|
String currentBirthday = binding.inputBirthday.getText() != null ? binding.inputBirthday.getText().toString() : "";
|
||||||
|
final int[] selectedYear = {currentYear - 25}; // 默认25岁
|
||||||
|
final int[] selectedMonth = {currentMonth};
|
||||||
|
final int[] selectedDay = {currentDay};
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(currentBirthday)) {
|
||||||
|
try {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
||||||
|
java.util.Date date = sdf.parse(currentBirthday);
|
||||||
|
if (date != null) {
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTime(date);
|
||||||
|
selectedYear[0] = cal.get(Calendar.YEAR);
|
||||||
|
selectedMonth[0] = cal.get(Calendar.MONTH) + 1;
|
||||||
|
selectedDay[0] = cal.get(Calendar.DAY_OF_MONTH);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 解析失败,使用默认值
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置年份范围:100年前到今天
|
||||||
|
int minYear = currentYear - 100;
|
||||||
|
int maxYear = currentYear;
|
||||||
|
yearPicker.setMinValue(minYear);
|
||||||
|
yearPicker.setMaxValue(maxYear);
|
||||||
|
yearPicker.setValue(selectedYear[0]);
|
||||||
|
yearPicker.setWrapSelectorWheel(false);
|
||||||
|
|
||||||
|
// 设置月份范围:1-12
|
||||||
|
monthPicker.setMinValue(1);
|
||||||
|
monthPicker.setMaxValue(12);
|
||||||
|
monthPicker.setValue(selectedMonth[0]);
|
||||||
|
monthPicker.setWrapSelectorWheel(false);
|
||||||
|
monthPicker.setDisplayedValues(new String[]{"1月", "2月", "3月", "4月", "5月", "6月",
|
||||||
|
"7月", "8月", "9月", "10月", "11月", "12月"});
|
||||||
|
|
||||||
|
// 更新日期选择器的最大值
|
||||||
|
updateDayPicker(dayPicker, selectedYear[0], selectedMonth[0], selectedDay[0]);
|
||||||
|
|
||||||
|
// 年份和月份变化时,更新日期选择器
|
||||||
|
yearPicker.setOnValueChangedListener((picker, oldVal, newVal) -> {
|
||||||
|
selectedYear[0] = newVal;
|
||||||
|
int maxDay = getDaysInMonth(selectedYear[0], selectedMonth[0]);
|
||||||
|
if (selectedDay[0] > maxDay) {
|
||||||
|
selectedDay[0] = maxDay;
|
||||||
|
}
|
||||||
|
updateDayPicker(dayPicker, selectedYear[0], selectedMonth[0], selectedDay[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
monthPicker.setOnValueChangedListener((picker, oldVal, newVal) -> {
|
||||||
|
selectedMonth[0] = newVal;
|
||||||
|
int maxDay = getDaysInMonth(selectedYear[0], selectedMonth[0]);
|
||||||
|
if (selectedDay[0] > maxDay) {
|
||||||
|
selectedDay[0] = maxDay;
|
||||||
|
}
|
||||||
|
updateDayPicker(dayPicker, selectedYear[0], selectedMonth[0], selectedDay[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 确认按钮
|
||||||
|
confirmButton.setOnClickListener(v -> {
|
||||||
|
int year = yearPicker.getValue();
|
||||||
|
int month = monthPicker.getValue();
|
||||||
|
int day = dayPicker.getValue();
|
||||||
|
|
||||||
|
// 格式化日期
|
||||||
|
Calendar selectedDate = Calendar.getInstance();
|
||||||
|
selectedDate.set(year, month - 1, day); // Calendar.MONTH 从0开始
|
||||||
|
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
||||||
|
String formattedDate = sdf.format(selectedDate.getTime());
|
||||||
|
|
||||||
|
// 更新输入框显示
|
||||||
|
binding.inputBirthday.setText(formattedDate);
|
||||||
|
|
||||||
|
// 立即保存到SharedPreferences
|
||||||
|
getSharedPreferences(PREFS_NAME, MODE_PRIVATE)
|
||||||
|
.edit()
|
||||||
|
.putString(KEY_BIRTHDAY, formattedDate)
|
||||||
|
.apply();
|
||||||
|
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
cancelButton.setOnClickListener(v -> dialog.dismiss());
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDayPicker(NumberPicker dayPicker, int year, int month, int selectedDay) {
|
||||||
|
int maxDay = getDaysInMonth(year, month);
|
||||||
|
dayPicker.setMinValue(1);
|
||||||
|
dayPicker.setMaxValue(maxDay);
|
||||||
|
dayPicker.setWrapSelectorWheel(false);
|
||||||
|
|
||||||
|
// 确保选中的日期不超过最大值
|
||||||
|
if (selectedDay > maxDay) {
|
||||||
|
selectedDay = maxDay;
|
||||||
|
}
|
||||||
|
dayPicker.setValue(selectedDay);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getDaysInMonth(int year, int month) {
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.set(year, month - 1, 1); // Calendar.MONTH 从0开始
|
||||||
|
return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.example.livestreaming.databinding.ActivityFindGameBinding;
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
|
public class FindGameActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private ActivityFindGameBinding binding;
|
||||||
|
|
||||||
|
public static void start(Context context) {
|
||||||
|
Intent intent = new Intent(context, FindGameActivity.class);
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
binding = ActivityFindGameBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
|
setupUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupUI() {
|
||||||
|
binding.backButton.setOnClickListener(v -> finish());
|
||||||
|
|
||||||
|
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
||||||
|
bottomNavigation.setSelectedItemId(R.id.nav_friends);
|
||||||
|
bottomNavigation.setOnItemSelectedListener(item -> {
|
||||||
|
int id = item.getItemId();
|
||||||
|
if (id == R.id.nav_home) {
|
||||||
|
startActivity(new Intent(this, MainActivity.class));
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_wish_tree) {
|
||||||
|
WishTreeActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_messages) {
|
||||||
|
MessagesActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_profile) {
|
||||||
|
ProfileActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
package com.example.livestreaming;
|
package com.example.livestreaming;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.view.HapticFeedbackConstants;
|
import android.view.HapticFeedbackConstants;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.animation.LinearInterpolator;
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
@ -70,12 +72,18 @@ public class FishPondActivity extends AppCompatActivity {
|
||||||
|
|
||||||
setupOrbitUserInteractions();
|
setupOrbitUserInteractions();
|
||||||
setupCenterRefresh();
|
setupCenterRefresh();
|
||||||
|
setupQuickActions();
|
||||||
|
loadCurrentUserInfo();
|
||||||
|
|
||||||
binding.orbitContainer.post(this::updateOrbitLayout);
|
binding.orbitContainer.post(this::updateOrbitLayout);
|
||||||
refreshUsers();
|
refreshUsers();
|
||||||
|
|
||||||
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
||||||
bottomNavigation.setSelectedItemId(R.id.nav_friends);
|
bottomNavigation.setSelectedItemId(R.id.nav_friends);
|
||||||
|
|
||||||
|
// 更新未读消息徽章
|
||||||
|
UnreadMessageManager.updateBadge(bottomNavigation);
|
||||||
|
|
||||||
bottomNavigation.setOnItemSelectedListener(item -> {
|
bottomNavigation.setOnItemSelectedListener(item -> {
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
if (id == R.id.nav_home) {
|
if (id == R.id.nav_home) {
|
||||||
|
|
@ -116,6 +124,54 @@ public class FishPondActivity extends AppCompatActivity {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupQuickActions() {
|
||||||
|
if (binding == null) return;
|
||||||
|
|
||||||
|
// 语音匹配按钮
|
||||||
|
binding.actionLeft.setOnClickListener(v -> {
|
||||||
|
VoiceMatchActivity.start(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 心动信号按钮
|
||||||
|
binding.actionRight.setOnClickListener(v -> {
|
||||||
|
HeartbeatSignalActivity.start(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取GridLayout中的卡片并设置点击事件
|
||||||
|
android.widget.GridLayout grid = binding.grid;
|
||||||
|
if (grid != null) {
|
||||||
|
int childCount = grid.getChildCount();
|
||||||
|
for (int i = 0; i < childCount && i < 6; i++) {
|
||||||
|
View card = grid.getChildAt(i);
|
||||||
|
if (card != null) {
|
||||||
|
final int index = i;
|
||||||
|
card.setOnClickListener(v -> {
|
||||||
|
switch (index) {
|
||||||
|
case 0: // 在线处对象
|
||||||
|
OnlineDatingActivity.start(this);
|
||||||
|
break;
|
||||||
|
case 1: // 找人玩游戏
|
||||||
|
FindGameActivity.start(this);
|
||||||
|
break;
|
||||||
|
case 2: // 一起KTV
|
||||||
|
KTVTogetherActivity.start(this);
|
||||||
|
break;
|
||||||
|
case 3: // 你画我猜
|
||||||
|
DrawGuessActivity.start(this);
|
||||||
|
break;
|
||||||
|
case 4: // 和平精英
|
||||||
|
PeaceEliteActivity.start(this);
|
||||||
|
break;
|
||||||
|
case 5: // 桌子游
|
||||||
|
TableGamesActivity.start(this);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateOrbitLayout() {
|
private void updateOrbitLayout() {
|
||||||
if (binding == null) return;
|
if (binding == null) return;
|
||||||
|
|
||||||
|
|
@ -227,6 +283,42 @@ public class FishPondActivity extends AppCompatActivity {
|
||||||
uiHandler.removeCallbacks(pulseRunnable);
|
uiHandler.removeCallbacks(pulseRunnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadCurrentUserInfo() {
|
||||||
|
if (binding == null) return;
|
||||||
|
|
||||||
|
SharedPreferences prefs = getSharedPreferences("profile_prefs", MODE_PRIVATE);
|
||||||
|
String name = prefs.getString("profile_name", "爱你");
|
||||||
|
String location = prefs.getString("profile_location", "广西");
|
||||||
|
String gender = prefs.getString("profile_gender", "");
|
||||||
|
|
||||||
|
// 设置右侧名称
|
||||||
|
binding.rightName.setText(name);
|
||||||
|
|
||||||
|
// 设置右侧信息:性别 | 地址 | 在线
|
||||||
|
String genderText = "";
|
||||||
|
if (!TextUtils.isEmpty(gender)) {
|
||||||
|
if (gender.contains("男")) {
|
||||||
|
genderText = "真诚";
|
||||||
|
} else if (gender.contains("女")) {
|
||||||
|
genderText = "真诚";
|
||||||
|
} else {
|
||||||
|
genderText = "真诚";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
genderText = "真诚";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理地址格式:如果是"省份-城市"格式,转换为"省份·城市"
|
||||||
|
String locationText = location;
|
||||||
|
if (!TextUtils.isEmpty(location) && location.contains("-")) {
|
||||||
|
locationText = location.replace("-", "·");
|
||||||
|
} else if (TextUtils.isEmpty(location)) {
|
||||||
|
locationText = "南宁";
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.rightInfo.setText(genderText + " | " + locationText + " | 在线");
|
||||||
|
}
|
||||||
|
|
||||||
private void refreshUsers() {
|
private void refreshUsers() {
|
||||||
if (binding == null) return;
|
if (binding == null) return;
|
||||||
|
|
||||||
|
|
@ -330,9 +422,15 @@ public class FishPondActivity extends AppCompatActivity {
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
if (binding != null) {
|
if (binding != null) {
|
||||||
binding.bottomNavInclude.bottomNavigation.setSelectedItemId(R.id.nav_friends);
|
BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation;
|
||||||
|
bottomNav.setSelectedItemId(R.id.nav_friends);
|
||||||
|
// 更新未读消息徽章
|
||||||
|
UnreadMessageManager.updateBadge(bottomNav);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 刷新当前用户信息(可能从编辑资料页面返回)
|
||||||
|
loadCurrentUserInfo();
|
||||||
|
|
||||||
// ensure radius computed before starting
|
// ensure radius computed before starting
|
||||||
if (binding != null) {
|
if (binding != null) {
|
||||||
binding.orbitContainer.post(() -> {
|
binding.orbitContainer.post(() -> {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.example.livestreaming.databinding.ActivityHeartbeatSignalBinding;
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
|
public class HeartbeatSignalActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private ActivityHeartbeatSignalBinding binding;
|
||||||
|
|
||||||
|
public static void start(Context context) {
|
||||||
|
Intent intent = new Intent(context, HeartbeatSignalActivity.class);
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
binding = ActivityHeartbeatSignalBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
|
setupUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupUI() {
|
||||||
|
binding.backButton.setOnClickListener(v -> finish());
|
||||||
|
|
||||||
|
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
||||||
|
bottomNavigation.setSelectedItemId(R.id.nav_friends);
|
||||||
|
bottomNavigation.setOnItemSelectedListener(item -> {
|
||||||
|
int id = item.getItemId();
|
||||||
|
if (id == R.id.nav_home) {
|
||||||
|
startActivity(new Intent(this, MainActivity.class));
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_wish_tree) {
|
||||||
|
WishTreeActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_messages) {
|
||||||
|
MessagesActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_profile) {
|
||||||
|
ProfileActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.example.livestreaming.databinding.ActivityKtvTogetherBinding;
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
|
public class KTVTogetherActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private ActivityKtvTogetherBinding binding;
|
||||||
|
|
||||||
|
public static void start(Context context) {
|
||||||
|
Intent intent = new Intent(context, KTVTogetherActivity.class);
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
binding = ActivityKtvTogetherBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
|
setupUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupUI() {
|
||||||
|
binding.backButton.setOnClickListener(v -> finish());
|
||||||
|
|
||||||
|
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
||||||
|
bottomNavigation.setSelectedItemId(R.id.nav_friends);
|
||||||
|
bottomNavigation.setOnItemSelectedListener(item -> {
|
||||||
|
int id = item.getItemId();
|
||||||
|
if (id == R.id.nav_home) {
|
||||||
|
startActivity(new Intent(this, MainActivity.class));
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_wish_tree) {
|
||||||
|
WishTreeActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_messages) {
|
||||||
|
MessagesActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_profile) {
|
||||||
|
ProfileActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class LocationDataManager {
|
||||||
|
private static LocationDataManager instance;
|
||||||
|
private List<Province> provinces;
|
||||||
|
private Map<String, Province> provinceMap;
|
||||||
|
|
||||||
|
private LocationDataManager() {
|
||||||
|
provinces = new ArrayList<>();
|
||||||
|
provinceMap = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized LocationDataManager getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new LocationDataManager();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadData(Context context) {
|
||||||
|
if (provinces != null && !provinces.isEmpty()) {
|
||||||
|
return; // 已经加载过
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
InputStream is = context.getAssets().open("location_data.json");
|
||||||
|
int size = is.available();
|
||||||
|
byte[] buffer = new byte[size];
|
||||||
|
is.read(buffer);
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
String json = new String(buffer, "UTF-8");
|
||||||
|
JSONObject jsonObject = new JSONObject(json);
|
||||||
|
JSONArray provincesArray = jsonObject.getJSONArray("provinces");
|
||||||
|
|
||||||
|
provinces.clear();
|
||||||
|
provinceMap.clear();
|
||||||
|
|
||||||
|
for (int i = 0; i < provincesArray.length(); i++) {
|
||||||
|
JSONObject provinceObj = provincesArray.getJSONObject(i);
|
||||||
|
Province province = new Province();
|
||||||
|
province.name = provinceObj.getString("name");
|
||||||
|
|
||||||
|
JSONArray citiesArray = provinceObj.getJSONArray("cities");
|
||||||
|
province.cities = new ArrayList<>();
|
||||||
|
for (int j = 0; j < citiesArray.length(); j++) {
|
||||||
|
JSONObject cityObj = citiesArray.getJSONObject(j);
|
||||||
|
City city = new City();
|
||||||
|
city.name = cityObj.getString("name");
|
||||||
|
province.cities.add(city);
|
||||||
|
}
|
||||||
|
|
||||||
|
provinces.add(province);
|
||||||
|
provinceMap.put(province.name, province);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getProvinceNames() {
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
for (Province province : provinces) {
|
||||||
|
names.add(province.name);
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getCityNames(String provinceName) {
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
Province province = provinceMap.get(provinceName);
|
||||||
|
if (province != null && province.cities != null) {
|
||||||
|
for (City city : province.cities) {
|
||||||
|
names.add(city.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String formatLocation(String province, String city) {
|
||||||
|
if (TextUtils.isEmpty(province)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (TextUtils.isEmpty(city)) {
|
||||||
|
return province;
|
||||||
|
}
|
||||||
|
return province + "-" + city;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] parseLocation(String location) {
|
||||||
|
if (TextUtils.isEmpty(location)) {
|
||||||
|
return new String[]{"", ""};
|
||||||
|
}
|
||||||
|
if (location.contains("-")) {
|
||||||
|
String[] parts = location.split("-", 2);
|
||||||
|
return new String[]{parts[0], parts.length > 1 ? parts[1] : ""};
|
||||||
|
}
|
||||||
|
return new String[]{location, ""};
|
||||||
|
}
|
||||||
|
|
||||||
|
public int findProvinceIndex(String provinceName) {
|
||||||
|
for (int i = 0; i < provinces.size(); i++) {
|
||||||
|
if (provinces.get(i).name.equals(provinceName)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int findCityIndex(String provinceName, String cityName) {
|
||||||
|
Province province = provinceMap.get(provinceName);
|
||||||
|
if (province != null && province.cities != null) {
|
||||||
|
for (int i = 0; i < province.cities.size(); i++) {
|
||||||
|
if (province.cities.get(i).name.equals(cityName)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Province {
|
||||||
|
String name;
|
||||||
|
List<City> cities;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class City {
|
||||||
|
String name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,21 @@
|
||||||
package com.example.livestreaming;
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.speech.RecognitionListener;
|
||||||
|
import android.speech.RecognizerIntent;
|
||||||
|
import android.speech.SpeechRecognizer;
|
||||||
|
import android.text.Editable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.text.TextWatcher;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
@ -16,6 +23,8 @@ import android.widget.Toast;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.core.view.GravityCompat;
|
import androidx.core.view.GravityCompat;
|
||||||
import androidx.drawerlayout.widget.DrawerLayout;
|
import androidx.drawerlayout.widget.DrawerLayout;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
@ -56,6 +65,11 @@ public class MainActivity extends AppCompatActivity {
|
||||||
private boolean isFetching;
|
private boolean isFetching;
|
||||||
private long lastFetchMs;
|
private long lastFetchMs;
|
||||||
|
|
||||||
|
private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200;
|
||||||
|
private SpeechRecognizer speechRecognizer;
|
||||||
|
private Intent speechRecognizerIntent;
|
||||||
|
private boolean isListening = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
@ -66,6 +80,29 @@ public class MainActivity extends AppCompatActivity {
|
||||||
setupRecyclerView();
|
setupRecyclerView();
|
||||||
setupUI();
|
setupUI();
|
||||||
loadAvatarFromPrefs();
|
loadAvatarFromPrefs();
|
||||||
|
setupSpeechRecognizer();
|
||||||
|
|
||||||
|
// 初始化未读消息数量(演示数据)
|
||||||
|
if (UnreadMessageManager.getUnreadCount(this) == 0) {
|
||||||
|
// 从消息列表计算总未读数量
|
||||||
|
UnreadMessageManager.setUnreadCount(this, calculateTotalUnreadCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除默认选中状态,让所有标签页初始显示为未选中样式
|
||||||
|
if (binding != null && binding.topTabs != null) {
|
||||||
|
// 在布局完成后清除默认选中状态
|
||||||
|
binding.topTabs.post(() -> {
|
||||||
|
// 清除所有选中状态
|
||||||
|
for (int i = 0; i < binding.topTabs.getTabCount(); i++) {
|
||||||
|
TabLayout.Tab tab = binding.topTabs.getTabAt(i);
|
||||||
|
if (tab != null && tab.isSelected()) {
|
||||||
|
// 取消选中,但不触发监听器
|
||||||
|
binding.topTabs.selectTab(null, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 异步加载资源文件,避免阻塞主线程
|
// 异步加载资源文件,避免阻塞主线程
|
||||||
loadCoverAssetsAsync();
|
loadCoverAssetsAsync();
|
||||||
|
|
@ -91,7 +128,7 @@ public class MainActivity extends AppCompatActivity {
|
||||||
items.add(new DrawerCardItem(DrawerCardItem.ACTION_PROFILE, "个人主页", "资料、作品、粉丝", R.drawable.ic_person_24));
|
items.add(new DrawerCardItem(DrawerCardItem.ACTION_PROFILE, "个人主页", "资料、作品、粉丝", R.drawable.ic_person_24));
|
||||||
items.add(new DrawerCardItem(DrawerCardItem.ACTION_MESSAGES, "消息", "私信、互动通知", R.drawable.ic_chat_24));
|
items.add(new DrawerCardItem(DrawerCardItem.ACTION_MESSAGES, "消息", "私信、互动通知", R.drawable.ic_chat_24));
|
||||||
items.add(new DrawerCardItem(DrawerCardItem.ACTION_MY_FRIENDS, "我的好友", "通讯录与挚友", R.drawable.ic_people_24));
|
items.add(new DrawerCardItem(DrawerCardItem.ACTION_MY_FRIENDS, "我的好友", "通讯录与挚友", R.drawable.ic_people_24));
|
||||||
items.add(new DrawerCardItem(DrawerCardItem.ACTION_FISH_POND, "鱼塘", "附近与社交圈", R.drawable.ic_globe_24));
|
items.add(new DrawerCardItem(DrawerCardItem.ACTION_FISH_POND, "缘池", "附近与社交圈", R.drawable.ic_people_24));
|
||||||
items.add(new DrawerCardItem(DrawerCardItem.ACTION_FOLLOWING, "我的关注", "你关注的主播", R.drawable.ic_people_24));
|
items.add(new DrawerCardItem(DrawerCardItem.ACTION_FOLLOWING, "我的关注", "你关注的主播", R.drawable.ic_people_24));
|
||||||
items.add(new DrawerCardItem(DrawerCardItem.ACTION_FANS, "粉丝", "关注你的人", R.drawable.ic_people_24));
|
items.add(new DrawerCardItem(DrawerCardItem.ACTION_FANS, "粉丝", "关注你的人", R.drawable.ic_people_24));
|
||||||
items.add(new DrawerCardItem(DrawerCardItem.ACTION_LIKES, "获赞", "收到的点赞", R.drawable.ic_heart_24));
|
items.add(new DrawerCardItem(DrawerCardItem.ACTION_LIKES, "获赞", "收到的点赞", R.drawable.ic_heart_24));
|
||||||
|
|
@ -204,12 +241,20 @@ public class MainActivity extends AppCompatActivity {
|
||||||
@Override
|
@Override
|
||||||
public void onTabSelected(TabLayout.Tab tab) {
|
public void onTabSelected(TabLayout.Tab tab) {
|
||||||
if (tab == null) return;
|
if (tab == null) return;
|
||||||
|
// 用户点击后,显示选中样式(显示指示器,改变文字颜色)
|
||||||
|
binding.topTabs.setSelectedTabIndicatorHeight(2); // 显示指示器
|
||||||
|
// 更新布局属性以显示选中样式
|
||||||
|
binding.topTabs.setTabTextColors(
|
||||||
|
getResources().getColor(android.R.color.darker_gray, null), // 未选中颜色
|
||||||
|
getResources().getColor(R.color.purple_500, null) // 选中颜色
|
||||||
|
);
|
||||||
CharSequence title = tab.getText();
|
CharSequence title = tab.getText();
|
||||||
TabPlaceholderActivity.start(MainActivity.this, title != null ? title.toString() : "");
|
TabPlaceholderActivity.start(MainActivity.this, title != null ? title.toString() : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTabUnselected(TabLayout.Tab tab) {
|
public void onTabUnselected(TabLayout.Tab tab) {
|
||||||
|
// 取消选中时,恢复默认样式
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -271,8 +316,15 @@ public class MainActivity extends AppCompatActivity {
|
||||||
// 设置添加直播按钮点击事件
|
// 设置添加直播按钮点击事件
|
||||||
binding.fabAddLive.setOnClickListener(v -> showCreateRoomDialog());
|
binding.fabAddLive.setOnClickListener(v -> showCreateRoomDialog());
|
||||||
|
|
||||||
|
// 设置搜索框文本监听和图标切换
|
||||||
|
setupSearchBox();
|
||||||
|
|
||||||
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
||||||
bottomNavigation.setSelectedItemId(R.id.nav_home);
|
bottomNavigation.setSelectedItemId(R.id.nav_home);
|
||||||
|
|
||||||
|
// 更新未读消息徽章
|
||||||
|
UnreadMessageManager.updateBadge(bottomNavigation);
|
||||||
|
|
||||||
bottomNavigation.setOnItemSelectedListener(item -> {
|
bottomNavigation.setOnItemSelectedListener(item -> {
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
if (id == R.id.nav_home) {
|
if (id == R.id.nav_home) {
|
||||||
|
|
@ -302,6 +354,245 @@ public class MainActivity extends AppCompatActivity {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupSearchBox() {
|
||||||
|
// 监听搜索框文本变化
|
||||||
|
binding.searchEdit.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
// 根据文本是否为空切换图标
|
||||||
|
String text = s != null ? s.toString().trim() : "";
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
// 文本为空,显示麦克风图标
|
||||||
|
binding.micIcon.setImageResource(R.drawable.ic_mic_24);
|
||||||
|
binding.micIcon.setContentDescription("mic");
|
||||||
|
} else {
|
||||||
|
// 文本不为空,显示搜索图标
|
||||||
|
binding.micIcon.setImageResource(R.drawable.ic_search_24);
|
||||||
|
binding.micIcon.setContentDescription("search");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 设置麦克风/搜索图标点击事件
|
||||||
|
binding.micIcon.setOnClickListener(v -> {
|
||||||
|
String searchText = binding.searchEdit.getText() != null ?
|
||||||
|
binding.searchEdit.getText().toString().trim() : "";
|
||||||
|
|
||||||
|
if (searchText.isEmpty()) {
|
||||||
|
// 如果文本为空,启动语音识别
|
||||||
|
startVoiceRecognition();
|
||||||
|
} else {
|
||||||
|
// 如果文本不为空,执行搜索
|
||||||
|
// 跳转到搜索页面并传递搜索关键词
|
||||||
|
SearchActivity.start(MainActivity.this, searchText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupSpeechRecognizer() {
|
||||||
|
// 检查设备是否支持语音识别
|
||||||
|
if (!SpeechRecognizer.isRecognitionAvailable(this)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
|
||||||
|
speechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
|
||||||
|
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
|
||||||
|
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "zh-CN"); // 设置为中文
|
||||||
|
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
|
||||||
|
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);
|
||||||
|
|
||||||
|
speechRecognizer.setRecognitionListener(new RecognitionListener() {
|
||||||
|
@Override
|
||||||
|
public void onReadyForSpeech(Bundle params) {
|
||||||
|
isListening = true;
|
||||||
|
// 可以在这里显示"正在聆听..."的提示
|
||||||
|
binding.micIcon.setAlpha(0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBeginningOfSpeech() {
|
||||||
|
// 开始说话
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRmsChanged(float rmsdB) {
|
||||||
|
// 音量变化,可以用来显示音量动画
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBufferReceived(byte[] buffer) {
|
||||||
|
// 接收音频数据
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEndOfSpeech() {
|
||||||
|
isListening = false;
|
||||||
|
binding.micIcon.setAlpha(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(int error) {
|
||||||
|
isListening = false;
|
||||||
|
binding.micIcon.setAlpha(1.0f);
|
||||||
|
|
||||||
|
String errorMessage;
|
||||||
|
switch (error) {
|
||||||
|
case SpeechRecognizer.ERROR_AUDIO:
|
||||||
|
errorMessage = "音频错误";
|
||||||
|
break;
|
||||||
|
case SpeechRecognizer.ERROR_CLIENT:
|
||||||
|
errorMessage = "客户端错误";
|
||||||
|
break;
|
||||||
|
case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
|
||||||
|
errorMessage = "权限不足";
|
||||||
|
requestAudioPermission();
|
||||||
|
return;
|
||||||
|
case SpeechRecognizer.ERROR_NETWORK:
|
||||||
|
errorMessage = "网络错误";
|
||||||
|
break;
|
||||||
|
case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
|
||||||
|
errorMessage = "网络超时";
|
||||||
|
break;
|
||||||
|
case SpeechRecognizer.ERROR_NO_MATCH:
|
||||||
|
errorMessage = "未识别到语音";
|
||||||
|
break;
|
||||||
|
case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
|
||||||
|
errorMessage = "识别器忙碌";
|
||||||
|
break;
|
||||||
|
case SpeechRecognizer.ERROR_SERVER:
|
||||||
|
errorMessage = "服务器错误";
|
||||||
|
break;
|
||||||
|
case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
|
||||||
|
errorMessage = "未检测到语音";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errorMessage = "未知错误";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只在非用户取消的情况下显示错误提示
|
||||||
|
if (error != SpeechRecognizer.ERROR_CLIENT) {
|
||||||
|
Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResults(Bundle results) {
|
||||||
|
isListening = false;
|
||||||
|
binding.micIcon.setAlpha(1.0f);
|
||||||
|
|
||||||
|
ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
|
||||||
|
if (matches != null && !matches.isEmpty()) {
|
||||||
|
String spokenText = matches.get(0);
|
||||||
|
// 将识别结果填充到搜索框
|
||||||
|
binding.searchEdit.setText(spokenText);
|
||||||
|
binding.searchEdit.setSelection(spokenText.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPartialResults(Bundle partialResults) {
|
||||||
|
// 部分结果,可以实时显示
|
||||||
|
ArrayList<String> matches = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
|
||||||
|
if (matches != null && !matches.isEmpty()) {
|
||||||
|
String partialText = matches.get(0);
|
||||||
|
// 可以在这里实时更新搜索框(可选)
|
||||||
|
// binding.searchEdit.setText(partialText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEvent(int eventType, Bundle params) {
|
||||||
|
// 事件回调
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startVoiceRecognition() {
|
||||||
|
// 检查权限
|
||||||
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
requestAudioPermission();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否正在监听
|
||||||
|
if (isListening) {
|
||||||
|
stopVoiceRecognition();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查SpeechRecognizer是否可用
|
||||||
|
if (speechRecognizer == null || speechRecognizerIntent == null) {
|
||||||
|
Toast.makeText(this, "语音识别功能不可用", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
speechRecognizer.startListening(speechRecognizerIntent);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Toast.makeText(this, "启动语音识别失败", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopVoiceRecognition() {
|
||||||
|
if (speechRecognizer != null && isListening) {
|
||||||
|
speechRecognizer.stopListening();
|
||||||
|
isListening = false;
|
||||||
|
binding.micIcon.setAlpha(1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void requestAudioPermission() {
|
||||||
|
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setTitle("需要麦克风权限")
|
||||||
|
.setMessage("语音搜索需要访问麦克风权限,请在设置中允许")
|
||||||
|
.setPositiveButton("确定", (dialog, which) -> {
|
||||||
|
ActivityCompat.requestPermissions(this,
|
||||||
|
new String[]{Manifest.permission.RECORD_AUDIO},
|
||||||
|
REQUEST_RECORD_AUDIO_PERMISSION);
|
||||||
|
})
|
||||||
|
.setNegativeButton("取消", null)
|
||||||
|
.show();
|
||||||
|
} else {
|
||||||
|
ActivityCompat.requestPermissions(this,
|
||||||
|
new String[]{Manifest.permission.RECORD_AUDIO},
|
||||||
|
REQUEST_RECORD_AUDIO_PERMISSION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
if (requestCode == REQUEST_RECORD_AUDIO_PERMISSION) {
|
||||||
|
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// 权限已授予,可以开始语音识别
|
||||||
|
startVoiceRecognition();
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "需要麦克风权限才能使用语音搜索", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (speechRecognizer != null) {
|
||||||
|
speechRecognizer.destroy();
|
||||||
|
speechRecognizer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void loadAvatarFromPrefs() {
|
private void loadAvatarFromPrefs() {
|
||||||
try {
|
try {
|
||||||
String avatarUri = getSharedPreferences("profile_prefs", MODE_PRIVATE)
|
String avatarUri = getSharedPreferences("profile_prefs", MODE_PRIVATE)
|
||||||
|
|
@ -340,9 +631,32 @@ public class MainActivity extends AppCompatActivity {
|
||||||
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
||||||
bottomNavigation.setSelectedItemId(R.id.nav_home);
|
bottomNavigation.setSelectedItemId(R.id.nav_home);
|
||||||
loadAvatarFromPrefs();
|
loadAvatarFromPrefs();
|
||||||
|
// 更新未读消息徽章
|
||||||
|
UnreadMessageManager.updateBadge(bottomNavigation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算总未读消息数量(从演示数据中计算)
|
||||||
|
*/
|
||||||
|
private int calculateTotalUnreadCount() {
|
||||||
|
// 模拟从消息列表计算总未读数量
|
||||||
|
// 这里使用 MessagesActivity 中的演示数据
|
||||||
|
int total = 0;
|
||||||
|
total += 2; // 系统通知
|
||||||
|
total += 5; // 附近的人
|
||||||
|
total += 19; // 直播间群聊
|
||||||
|
total += 1; // 客服
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
// 暂停时停止语音识别
|
||||||
|
stopVoiceRecognition();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,11 @@ public class MessagesActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private int swipedPosition = RecyclerView.NO_POSITION;
|
private int swipedPosition = RecyclerView.NO_POSITION;
|
||||||
private RectF deleteButtonRect;
|
private RectF deleteButtonRect;
|
||||||
|
private RectF markReadButtonRect;
|
||||||
private final Paint deleteBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
private final Paint deleteBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
private final Paint deleteTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
private final Paint deleteTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
private final Paint markReadBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
private final Paint markReadTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
|
||||||
private int lastSwipePosition = RecyclerView.NO_POSITION;
|
private int lastSwipePosition = RecyclerView.NO_POSITION;
|
||||||
private float lastSwipeDx;
|
private float lastSwipeDx;
|
||||||
|
|
@ -89,14 +92,35 @@ public class MessagesActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupConversationList() {
|
private void setupConversationList() {
|
||||||
|
// 删除按钮的背景颜色(红色)
|
||||||
deleteBackgroundPaint.setColor(0xFFE53935);
|
deleteBackgroundPaint.setColor(0xFFE53935);
|
||||||
deleteTextPaint.setColor(Color.WHITE);
|
deleteTextPaint.setColor(Color.WHITE);
|
||||||
deleteTextPaint.setTextAlign(Paint.Align.CENTER);
|
deleteTextPaint.setTextAlign(Paint.Align.CENTER);
|
||||||
deleteTextPaint.setTextSize(sp(14));
|
deleteTextPaint.setTextSize(sp(14));
|
||||||
|
|
||||||
|
// 标记已读按钮的背景颜色(蓝色)
|
||||||
|
markReadBackgroundPaint.setColor(0xFF2196F3);
|
||||||
|
markReadTextPaint.setColor(Color.WHITE);
|
||||||
|
markReadTextPaint.setTextAlign(Paint.Align.CENTER);
|
||||||
|
markReadTextPaint.setTextSize(sp(14));
|
||||||
|
|
||||||
conversationsAdapter = new ConversationsAdapter(item -> {
|
conversationsAdapter = new ConversationsAdapter(item -> {
|
||||||
if (item == null) return;
|
if (item == null) return;
|
||||||
ConversationActivity.start(this, item.getId(), item.getTitle());
|
// 启动会话页面,传递未读数量
|
||||||
|
Intent intent = new Intent(this, ConversationActivity.class);
|
||||||
|
intent.putExtra("extra_conversation_id", item.getId());
|
||||||
|
intent.putExtra("extra_conversation_title", item.getTitle());
|
||||||
|
intent.putExtra("extra_unread_count", item.getUnreadCount());
|
||||||
|
startActivity(intent);
|
||||||
|
|
||||||
|
// 用户点击会话时,减少该会话的未读数量
|
||||||
|
if (item.getUnreadCount() > 0) {
|
||||||
|
// 更新该会话的未读数量为0(在实际应用中,这里应该更新数据源)
|
||||||
|
// 然后更新总未读数量
|
||||||
|
UnreadMessageManager.decrementUnreadCount(this, item.getUnreadCount());
|
||||||
|
// 更新列表中的未读数量显示
|
||||||
|
updateConversationUnreadCount(item.getId(), 0);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
binding.conversationsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
|
binding.conversationsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||||
binding.conversationsRecyclerView.setAdapter(conversationsAdapter);
|
binding.conversationsRecyclerView.setAdapter(conversationsAdapter);
|
||||||
|
|
@ -109,7 +133,9 @@ public class MessagesActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attachSwipeToDelete(RecyclerView recyclerView) {
|
private void attachSwipeToDelete(RecyclerView recyclerView) {
|
||||||
final float actionWidth = dp(96);
|
// 两个按钮的总宽度:删除按钮 + 标记已读按钮
|
||||||
|
final float buttonWidth = dp(96);
|
||||||
|
final float actionWidth = buttonWidth * 2; // 两个按钮并排显示
|
||||||
touchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
|
touchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
|
||||||
ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
|
ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -140,6 +166,7 @@ public class MessagesActivity extends AppCompatActivity {
|
||||||
int old = swipedPosition;
|
int old = swipedPosition;
|
||||||
swipedPosition = RecyclerView.NO_POSITION;
|
swipedPosition = RecyclerView.NO_POSITION;
|
||||||
deleteButtonRect = null;
|
deleteButtonRect = null;
|
||||||
|
markReadButtonRect = null;
|
||||||
conversationsAdapter.notifyItemChanged(old);
|
conversationsAdapter.notifyItemChanged(old);
|
||||||
}
|
}
|
||||||
swipedPosition = pos;
|
swipedPosition = pos;
|
||||||
|
|
@ -148,6 +175,7 @@ public class MessagesActivity extends AppCompatActivity {
|
||||||
if (swipedPosition == pos) {
|
if (swipedPosition == pos) {
|
||||||
swipedPosition = RecyclerView.NO_POSITION;
|
swipedPosition = RecyclerView.NO_POSITION;
|
||||||
deleteButtonRect = null;
|
deleteButtonRect = null;
|
||||||
|
markReadButtonRect = null;
|
||||||
}
|
}
|
||||||
viewHolder.itemView.setTranslationX(0f);
|
viewHolder.itemView.setTranslationX(0f);
|
||||||
}
|
}
|
||||||
|
|
@ -207,20 +235,37 @@ public class MessagesActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
View itemView = viewHolder.itemView;
|
View itemView = viewHolder.itemView;
|
||||||
float left;
|
|
||||||
float top = itemView.getTop();
|
float top = itemView.getTop();
|
||||||
float bottom = itemView.getBottom();
|
float bottom = itemView.getBottom();
|
||||||
float right = itemView.getRight();
|
float right = itemView.getRight();
|
||||||
left = right + clampedDx;
|
float left = right + clampedDx;
|
||||||
|
|
||||||
deleteButtonRect = new RectF(left, top, right, bottom);
|
// 绘制两个按钮:标记已读(左侧)和删除(右侧)
|
||||||
|
final float buttonWidth = dp(96);
|
||||||
|
|
||||||
|
// 标记已读按钮(左侧,蓝色)
|
||||||
|
float markReadLeft = left;
|
||||||
|
float markReadRight = left + buttonWidth;
|
||||||
|
markReadButtonRect = new RectF(markReadLeft, top, markReadRight, bottom);
|
||||||
|
c.drawRect(markReadButtonRect, markReadBackgroundPaint);
|
||||||
|
|
||||||
|
float markReadCenterX = markReadButtonRect.centerX();
|
||||||
|
float markReadCenterY = markReadButtonRect.centerY();
|
||||||
|
Paint.FontMetrics markReadFm = markReadTextPaint.getFontMetrics();
|
||||||
|
float markReadTextY = markReadCenterY - (markReadFm.ascent + markReadFm.descent) / 2f;
|
||||||
|
c.drawText("标记已读", markReadCenterX, markReadTextY, markReadTextPaint);
|
||||||
|
|
||||||
|
// 删除按钮(右侧,红色)
|
||||||
|
float deleteLeft = markReadRight;
|
||||||
|
float deleteRight = right;
|
||||||
|
deleteButtonRect = new RectF(deleteLeft, top, deleteRight, bottom);
|
||||||
c.drawRect(deleteButtonRect, deleteBackgroundPaint);
|
c.drawRect(deleteButtonRect, deleteBackgroundPaint);
|
||||||
|
|
||||||
float centerX = deleteButtonRect.centerX();
|
float deleteCenterX = deleteButtonRect.centerX();
|
||||||
float centerY = deleteButtonRect.centerY();
|
float deleteCenterY = deleteButtonRect.centerY();
|
||||||
Paint.FontMetrics fm = deleteTextPaint.getFontMetrics();
|
Paint.FontMetrics deleteFm = deleteTextPaint.getFontMetrics();
|
||||||
float textY = centerY - (fm.ascent + fm.descent) / 2f;
|
float deleteTextY = deleteCenterY - (deleteFm.ascent + deleteFm.descent) / 2f;
|
||||||
c.drawText("删除", centerX, textY, deleteTextPaint);
|
c.drawText("删除", deleteCenterX, deleteTextY, deleteTextPaint);
|
||||||
|
|
||||||
super.onChildDraw(c, recyclerView, viewHolder, clampedDx, dY, actionState, isCurrentlyActive);
|
super.onChildDraw(c, recyclerView, viewHolder, clampedDx, dY, actionState, isCurrentlyActive);
|
||||||
}
|
}
|
||||||
|
|
@ -229,7 +274,7 @@ public class MessagesActivity extends AppCompatActivity {
|
||||||
new ItemTouchHelper(callback).attachToRecyclerView(recyclerView);
|
new ItemTouchHelper(callback).attachToRecyclerView(recyclerView);
|
||||||
|
|
||||||
recyclerView.setOnTouchListener((v, event) -> {
|
recyclerView.setOnTouchListener((v, event) -> {
|
||||||
if (swipedPosition == RecyclerView.NO_POSITION || deleteButtonRect == null) return false;
|
if (swipedPosition == RecyclerView.NO_POSITION || (deleteButtonRect == null && markReadButtonRect == null)) return false;
|
||||||
|
|
||||||
int action = event.getActionMasked();
|
int action = event.getActionMasked();
|
||||||
if (action == MotionEvent.ACTION_DOWN) {
|
if (action == MotionEvent.ACTION_DOWN) {
|
||||||
|
|
@ -251,10 +296,20 @@ public class MessagesActivity extends AppCompatActivity {
|
||||||
if (action == MotionEvent.ACTION_UP) {
|
if (action == MotionEvent.ACTION_UP) {
|
||||||
if (!touchIsClick) return false;
|
if (!touchIsClick) return false;
|
||||||
|
|
||||||
boolean hit = deleteButtonRect.contains(event.getX(), event.getY());
|
|
||||||
int pos = swipedPosition;
|
int pos = swipedPosition;
|
||||||
|
float x = event.getX();
|
||||||
|
float y = event.getY();
|
||||||
|
|
||||||
|
// 检查点击的是哪个按钮
|
||||||
|
boolean hitMarkRead = markReadButtonRect != null && markReadButtonRect.contains(x, y);
|
||||||
|
boolean hitDelete = deleteButtonRect != null && deleteButtonRect.contains(x, y);
|
||||||
|
|
||||||
recoverSwipedItem();
|
recoverSwipedItem();
|
||||||
if (hit) {
|
|
||||||
|
if (hitMarkRead) {
|
||||||
|
markAsReadAt(pos);
|
||||||
|
return true;
|
||||||
|
} else if (hitDelete) {
|
||||||
deleteConversationAt(pos);
|
deleteConversationAt(pos);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -267,17 +322,56 @@ public class MessagesActivity extends AppCompatActivity {
|
||||||
int pos = swipedPosition;
|
int pos = swipedPosition;
|
||||||
swipedPosition = RecyclerView.NO_POSITION;
|
swipedPosition = RecyclerView.NO_POSITION;
|
||||||
deleteButtonRect = null;
|
deleteButtonRect = null;
|
||||||
|
markReadButtonRect = null;
|
||||||
if (pos != RecyclerView.NO_POSITION && conversationsAdapter != null) {
|
if (pos != RecyclerView.NO_POSITION && conversationsAdapter != null) {
|
||||||
conversationsAdapter.notifyItemChanged(pos);
|
conversationsAdapter.notifyItemChanged(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标记会话为已读
|
||||||
|
*/
|
||||||
|
private void markAsReadAt(int position) {
|
||||||
|
if (position < 0 || position >= conversations.size()) return;
|
||||||
|
|
||||||
|
ConversationItem item = conversations.get(position);
|
||||||
|
if (item == null) return;
|
||||||
|
|
||||||
|
// 获取该会话的未读数量
|
||||||
|
int unreadCount = item.getUnreadCount();
|
||||||
|
|
||||||
|
// 如果已经有未读消息,才需要更新
|
||||||
|
if (unreadCount > 0) {
|
||||||
|
// 将该会话的未读数量设为0
|
||||||
|
// updateConversationUnreadCount 方法会自动重新计算总未读数量并更新徽章
|
||||||
|
updateConversationUnreadCount(item.getId(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除会话
|
||||||
|
*/
|
||||||
private void deleteConversationAt(int position) {
|
private void deleteConversationAt(int position) {
|
||||||
if (position < 0 || position >= conversations.size()) return;
|
if (position < 0 || position >= conversations.size()) return;
|
||||||
|
|
||||||
|
// 获取要删除的会话的未读数量
|
||||||
|
ConversationItem itemToDelete = conversations.get(position);
|
||||||
|
int unreadCountToRemove = itemToDelete != null ? itemToDelete.getUnreadCount() : 0;
|
||||||
|
|
||||||
|
// 删除会话
|
||||||
conversations.remove(position);
|
conversations.remove(position);
|
||||||
if (conversationsAdapter != null) {
|
if (conversationsAdapter != null) {
|
||||||
conversationsAdapter.submitList(new ArrayList<>(conversations));
|
conversationsAdapter.submitList(new ArrayList<>(conversations));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新总未读数量:减少被删除会话的未读数量
|
||||||
|
if (unreadCountToRemove > 0) {
|
||||||
|
UnreadMessageManager.decrementUnreadCount(this, unreadCountToRemove);
|
||||||
|
// 更新底部导航栏徽章
|
||||||
|
if (binding != null) {
|
||||||
|
UnreadMessageManager.updateBadge(binding.bottomNavInclude.bottomNavigation);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float dp(float value) {
|
private float dp(float value) {
|
||||||
|
|
@ -304,7 +398,65 @@ public class MessagesActivity extends AppCompatActivity {
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
if (binding != null) {
|
if (binding != null) {
|
||||||
binding.bottomNavInclude.bottomNavigation.setSelectedItemId(R.id.nav_messages);
|
BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation;
|
||||||
|
bottomNav.setSelectedItemId(R.id.nav_messages);
|
||||||
|
|
||||||
|
// 用户进入消息页面时,计算并更新总未读数量
|
||||||
|
int totalUnread = calculateTotalUnreadCount();
|
||||||
|
UnreadMessageManager.setUnreadCount(this, totalUnread);
|
||||||
|
UnreadMessageManager.updateBadge(bottomNav);
|
||||||
|
|
||||||
|
// 刷新列表以更新未读数量显示
|
||||||
|
if (conversationsAdapter != null) {
|
||||||
|
conversationsAdapter.submitList(new ArrayList<>(conversations));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算总未读消息数量
|
||||||
|
*/
|
||||||
|
private int calculateTotalUnreadCount() {
|
||||||
|
int total = 0;
|
||||||
|
for (ConversationItem item : conversations) {
|
||||||
|
if (item != null) {
|
||||||
|
total += item.getUnreadCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新会话的未读数量
|
||||||
|
*/
|
||||||
|
private void updateConversationUnreadCount(String conversationId, int newUnreadCount) {
|
||||||
|
for (int i = 0; i < conversations.size(); i++) {
|
||||||
|
ConversationItem item = conversations.get(i);
|
||||||
|
if (item != null && item.getId().equals(conversationId)) {
|
||||||
|
// 创建新的 ConversationItem,更新未读数量
|
||||||
|
conversations.set(i, new ConversationItem(
|
||||||
|
item.getId(),
|
||||||
|
item.getTitle(),
|
||||||
|
item.getLastMessage(),
|
||||||
|
item.getTimeText(),
|
||||||
|
newUnreadCount,
|
||||||
|
item.isMuted()
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通知适配器更新列表显示
|
||||||
|
if (conversationsAdapter != null) {
|
||||||
|
conversationsAdapter.submitList(new ArrayList<>(conversations));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新总未读数量
|
||||||
|
int totalUnread = calculateTotalUnreadCount();
|
||||||
|
UnreadMessageManager.setUnreadCount(this, totalUnread);
|
||||||
|
// 更新底部导航栏徽章
|
||||||
|
if (binding != null) {
|
||||||
|
UnreadMessageManager.updateBadge(binding.bottomNavInclude.bottomNavigation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
|
||||||
import androidx.recyclerview.widget.DiffUtil;
|
import androidx.recyclerview.widget.DiffUtil;
|
||||||
import androidx.recyclerview.widget.ListAdapter;
|
import androidx.recyclerview.widget.ListAdapter;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
@ -50,37 +49,25 @@ public class NearbyUsersAdapter extends ListAdapter<NearbyUser, NearbyUsersAdapt
|
||||||
|
|
||||||
void bind(NearbyUser user) {
|
void bind(NearbyUser user) {
|
||||||
binding.userName.setText(user != null && user.getName() != null ? user.getName() : "");
|
binding.userName.setText(user != null && user.getName() != null ? user.getName() : "");
|
||||||
binding.distanceText.setText(user != null && user.getDistanceText() != null ? user.getDistanceText() : "");
|
|
||||||
|
|
||||||
try {
|
// 格式化距离文本
|
||||||
String seed = user != null && user.getId() != null ? user.getId() : String.valueOf(getBindingAdapterPosition());
|
String distanceText = user != null && user.getDistanceText() != null ? user.getDistanceText() : "";
|
||||||
int h = Math.abs(seed.hashCode());
|
if (!distanceText.isEmpty() && !distanceText.startsWith("距离")) {
|
||||||
int mode = h % 3;
|
binding.distanceText.setText("距离 " + distanceText);
|
||||||
String ratio;
|
|
||||||
if (mode == 0) {
|
|
||||||
ratio = "1:1";
|
|
||||||
} else if (mode == 1) {
|
|
||||||
ratio = "3:4";
|
|
||||||
} else {
|
} else {
|
||||||
ratio = "4:3";
|
binding.distanceText.setText(distanceText);
|
||||||
}
|
|
||||||
ViewGroup.LayoutParams lp = binding.avatarImage.getLayoutParams();
|
|
||||||
if (lp instanceof ConstraintLayout.LayoutParams) {
|
|
||||||
ConstraintLayout.LayoutParams clp = (ConstraintLayout.LayoutParams) lp;
|
|
||||||
if (clp.dimensionRatio == null || !clp.dimensionRatio.equals(ratio)) {
|
|
||||||
clp.dimensionRatio = ratio;
|
|
||||||
binding.avatarImage.setLayoutParams(clp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user != null && user.isLive()) {
|
// 设置头像(使用简单的占位符,不再使用动态比例)
|
||||||
binding.liveBadge.setVisibility(View.VISIBLE);
|
// 头像已经在布局中固定为圆形,不需要动态调整
|
||||||
} else {
|
|
||||||
binding.liveBadge.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 添加按钮点击事件
|
||||||
|
binding.addButton.setOnClickListener(v -> {
|
||||||
|
if (user == null) return;
|
||||||
|
if (onUserClickListener != null) onUserClickListener.onUserClick(user);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 整个item点击也可以触发添加
|
||||||
binding.getRoot().setOnClickListener(v -> {
|
binding.getRoot().setOnClickListener(v -> {
|
||||||
if (user == null) return;
|
if (user == null) return;
|
||||||
if (onUserClickListener != null) onUserClickListener.onUserClick(user);
|
if (onUserClickListener != null) onUserClickListener.onUserClick(user);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.example.livestreaming.databinding.ActivityOnlineDatingBinding;
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
|
public class OnlineDatingActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private ActivityOnlineDatingBinding binding;
|
||||||
|
|
||||||
|
public static void start(Context context) {
|
||||||
|
Intent intent = new Intent(context, OnlineDatingActivity.class);
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
binding = ActivityOnlineDatingBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
|
setupUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupUI() {
|
||||||
|
binding.backButton.setOnClickListener(v -> finish());
|
||||||
|
|
||||||
|
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
||||||
|
bottomNavigation.setSelectedItemId(R.id.nav_friends);
|
||||||
|
bottomNavigation.setOnItemSelectedListener(item -> {
|
||||||
|
int id = item.getItemId();
|
||||||
|
if (id == R.id.nav_home) {
|
||||||
|
startActivity(new Intent(this, MainActivity.class));
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_wish_tree) {
|
||||||
|
WishTreeActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_messages) {
|
||||||
|
MessagesActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_profile) {
|
||||||
|
ProfileActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.example.livestreaming.databinding.ActivityPeaceEliteBinding;
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
|
public class PeaceEliteActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private ActivityPeaceEliteBinding binding;
|
||||||
|
|
||||||
|
public static void start(Context context) {
|
||||||
|
Intent intent = new Intent(context, PeaceEliteActivity.class);
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
binding = ActivityPeaceEliteBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
|
setupUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupUI() {
|
||||||
|
binding.backButton.setOnClickListener(v -> finish());
|
||||||
|
|
||||||
|
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
||||||
|
bottomNavigation.setSelectedItemId(R.id.nav_friends);
|
||||||
|
bottomNavigation.setOnItemSelectedListener(item -> {
|
||||||
|
int id = item.getItemId();
|
||||||
|
if (id == R.id.nav_home) {
|
||||||
|
startActivity(new Intent(this, MainActivity.class));
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_wish_tree) {
|
||||||
|
WishTreeActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_messages) {
|
||||||
|
MessagesActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_profile) {
|
||||||
|
ProfileActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -4,6 +4,7 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
@ -11,6 +12,9 @@ import android.view.View;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
|
|
@ -18,6 +22,12 @@ import com.bumptech.glide.Glide;
|
||||||
import com.example.livestreaming.databinding.ActivityProfileBinding;
|
import com.example.livestreaming.databinding.ActivityProfileBinding;
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class ProfileActivity extends AppCompatActivity {
|
public class ProfileActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private ActivityProfileBinding binding;
|
private ActivityProfileBinding binding;
|
||||||
|
|
@ -36,6 +46,8 @@ public class ProfileActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private static final String BIO_HINT_TEXT = "填写个人签名更容易获得关注,点击此处添加";
|
private static final String BIO_HINT_TEXT = "填写个人签名更容易获得关注,点击此处添加";
|
||||||
|
|
||||||
|
private ActivityResultLauncher<Intent> editProfileLauncher;
|
||||||
|
|
||||||
public static void start(Context context) {
|
public static void start(Context context) {
|
||||||
Intent intent = new Intent(context, ProfileActivity.class);
|
Intent intent = new Intent(context, ProfileActivity.class);
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
|
|
@ -47,13 +59,31 @@ public class ProfileActivity extends AppCompatActivity {
|
||||||
binding = ActivityProfileBinding.inflate(getLayoutInflater());
|
binding = ActivityProfileBinding.inflate(getLayoutInflater());
|
||||||
setContentView(binding.getRoot());
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
|
// 注册编辑资料页面的结果监听
|
||||||
|
editProfileLauncher = registerForActivityResult(
|
||||||
|
new ActivityResultContracts.StartActivityForResult(),
|
||||||
|
result -> {
|
||||||
|
// 当从EditProfileActivity返回时,立即刷新所有数据
|
||||||
loadProfileFromPrefs();
|
loadProfileFromPrefs();
|
||||||
|
loadAndDisplayTags();
|
||||||
|
loadProfileInfo();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
loadProfileFromPrefs();
|
||||||
|
loadAndDisplayTags();
|
||||||
|
loadProfileInfo();
|
||||||
setupEditableAreas();
|
setupEditableAreas();
|
||||||
|
setupAvatarClick();
|
||||||
setupNavigationClicks();
|
setupNavigationClicks();
|
||||||
setupProfileTabs();
|
setupProfileTabs();
|
||||||
|
|
||||||
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
||||||
bottomNavigation.setSelectedItemId(R.id.nav_profile);
|
bottomNavigation.setSelectedItemId(R.id.nav_profile);
|
||||||
|
|
||||||
|
// 更新未读消息徽章
|
||||||
|
UnreadMessageManager.updateBadge(bottomNavigation);
|
||||||
|
|
||||||
bottomNavigation.setOnItemSelectedListener(item -> {
|
bottomNavigation.setOnItemSelectedListener(item -> {
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
if (id == R.id.nav_home) {
|
if (id == R.id.nav_home) {
|
||||||
|
|
@ -140,6 +170,32 @@ public class ProfileActivity extends AppCompatActivity {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupAvatarClick() {
|
||||||
|
binding.avatar.setOnClickListener(v -> {
|
||||||
|
AvatarViewerDialog dialog = AvatarViewerDialog.create(this);
|
||||||
|
|
||||||
|
// 优先从SharedPreferences读取最新的头像信息(因为ImageView可能还在加载中)
|
||||||
|
String avatarUri = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_AVATAR_URI, null);
|
||||||
|
int avatarRes = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getInt(KEY_AVATAR_RES, 0);
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(avatarUri)) {
|
||||||
|
// 使用URI加载,确保能正确显示
|
||||||
|
dialog.setAvatarUri(Uri.parse(avatarUri));
|
||||||
|
} else if (avatarRes != 0) {
|
||||||
|
dialog.setAvatarResId(avatarRes);
|
||||||
|
} else {
|
||||||
|
// 如果都没有,尝试从ImageView获取Drawable
|
||||||
|
Drawable drawable = binding.avatar.getDrawable();
|
||||||
|
if (drawable != null) {
|
||||||
|
dialog.setAvatarDrawable(drawable);
|
||||||
|
} else {
|
||||||
|
dialog.setAvatarResId(R.drawable.ic_account_circle_24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dialog.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void setupNavigationClicks() {
|
private void setupNavigationClicks() {
|
||||||
binding.topActionSearch.setOnClickListener(v -> TabPlaceholderActivity.start(this, "定位/发现"));
|
binding.topActionSearch.setOnClickListener(v -> TabPlaceholderActivity.start(this, "定位/发现"));
|
||||||
binding.topActionClock.setOnClickListener(v -> WatchHistoryActivity.start(this));
|
binding.topActionClock.setOnClickListener(v -> WatchHistoryActivity.start(this));
|
||||||
|
|
@ -161,13 +217,14 @@ public class ProfileActivity extends AppCompatActivity {
|
||||||
binding.followers.setOnClickListener(v -> FansListActivity.start(this));
|
binding.followers.setOnClickListener(v -> FansListActivity.start(this));
|
||||||
binding.likes.setOnClickListener(v -> LikesListActivity.start(this));
|
binding.likes.setOnClickListener(v -> LikesListActivity.start(this));
|
||||||
|
|
||||||
binding.recordBtn.setOnClickListener(v -> Toast.makeText(this, "录制声音(待实现)", Toast.LENGTH_SHORT).show());
|
|
||||||
|
|
||||||
binding.action1.setOnClickListener(v -> TabPlaceholderActivity.start(this, "公园勋章"));
|
binding.action1.setOnClickListener(v -> TabPlaceholderActivity.start(this, "公园勋章"));
|
||||||
binding.action2.setOnClickListener(v -> WatchHistoryActivity.start(this));
|
binding.action2.setOnClickListener(v -> WatchHistoryActivity.start(this));
|
||||||
binding.action3.setOnClickListener(v -> startActivity(new Intent(this, MyFriendsActivity.class)));
|
binding.action3.setOnClickListener(v -> startActivity(new Intent(this, MyFriendsActivity.class)));
|
||||||
|
|
||||||
binding.editProfile.setOnClickListener(v -> EditProfileActivity.start(this));
|
binding.editProfile.setOnClickListener(v -> {
|
||||||
|
Intent intent = new Intent(this, EditProfileActivity.class);
|
||||||
|
editProfileLauncher.launch(intent);
|
||||||
|
});
|
||||||
binding.shareHome.setOnClickListener(v -> {
|
binding.shareHome.setOnClickListener(v -> {
|
||||||
// TabPlaceholderActivity.start(this, "分享主页");
|
// TabPlaceholderActivity.start(this, "分享主页");
|
||||||
String idText = binding.idLine.getText() != null ? binding.idLine.getText().toString() : "";
|
String idText = binding.idLine.getText() != null ? binding.idLine.getText().toString() : "";
|
||||||
|
|
@ -209,14 +266,18 @@ public class ProfileActivity extends AppCompatActivity {
|
||||||
binding.worksPublishBtn.setOnClickListener(v -> Toast.makeText(this, "发布功能待接入", Toast.LENGTH_SHORT).show());
|
binding.worksPublishBtn.setOnClickListener(v -> Toast.makeText(this, "发布功能待接入", Toast.LENGTH_SHORT).show());
|
||||||
binding.likedGoBrowseBtn.setOnClickListener(v -> startActivity(new Intent(this, MainActivity.class)));
|
binding.likedGoBrowseBtn.setOnClickListener(v -> startActivity(new Intent(this, MainActivity.class)));
|
||||||
binding.favGoBrowseBtn.setOnClickListener(v -> startActivity(new Intent(this, MainActivity.class)));
|
binding.favGoBrowseBtn.setOnClickListener(v -> startActivity(new Intent(this, MainActivity.class)));
|
||||||
binding.profileEditFromTab.setOnClickListener(v -> EditProfileActivity.start(this));
|
binding.profileEditFromTab.setOnClickListener(v -> {
|
||||||
|
Intent intent = new Intent(this, EditProfileActivity.class);
|
||||||
|
editProfileLauncher.launch(intent);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showTab(int index) {
|
private void showTab(int index) {
|
||||||
|
// 标签页顺序:0-作品, 1-收藏, 2-赞过
|
||||||
binding.tabWorks.setVisibility(index == 0 ? View.VISIBLE : View.GONE);
|
binding.tabWorks.setVisibility(index == 0 ? View.VISIBLE : View.GONE);
|
||||||
binding.tabLiked.setVisibility(index == 1 ? View.VISIBLE : View.GONE);
|
binding.tabFavorites.setVisibility(index == 1 ? View.VISIBLE : View.GONE);
|
||||||
binding.tabFavorites.setVisibility(index == 2 ? View.VISIBLE : View.GONE);
|
binding.tabLiked.setVisibility(index == 2 ? View.VISIBLE : View.GONE);
|
||||||
binding.tabProfile.setVisibility(index == 3 ? View.VISIBLE : View.GONE);
|
// "资料"标签页已移除
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface OnTextSaved {
|
private interface OnTextSaved {
|
||||||
|
|
@ -251,7 +312,153 @@ public class ProfileActivity extends AppCompatActivity {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
if (binding != null) {
|
if (binding != null) {
|
||||||
loadProfileFromPrefs();
|
loadProfileFromPrefs();
|
||||||
binding.bottomNavInclude.bottomNavigation.setSelectedItemId(R.id.nav_profile);
|
loadAndDisplayTags();
|
||||||
|
loadProfileInfo();
|
||||||
|
BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation;
|
||||||
|
bottomNav.setSelectedItemId(R.id.nav_profile);
|
||||||
|
// 更新未读消息徽章
|
||||||
|
UnreadMessageManager.updateBadge(bottomNav);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadAndDisplayTags() {
|
||||||
|
String location = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_LOCATION, "");
|
||||||
|
String gender = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_GENDER, "");
|
||||||
|
String birthday = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_BIRTHDAY, "");
|
||||||
|
|
||||||
|
// 设置所在地标签 - 支持"省份-城市"格式
|
||||||
|
if (!TextUtils.isEmpty(location)) {
|
||||||
|
// 将"省份-城市"格式转换为"省份·城市"显示
|
||||||
|
String displayLocation = location.replace("-", "·");
|
||||||
|
binding.tagLocation.setText("IP:" + displayLocation);
|
||||||
|
binding.tagLocation.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
binding.tagLocation.setText("IP:广西");
|
||||||
|
binding.tagLocation.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置性别标签
|
||||||
|
if (!TextUtils.isEmpty(gender)) {
|
||||||
|
if (gender.contains("男")) {
|
||||||
|
binding.tagGender.setText("男");
|
||||||
|
} else if (gender.contains("女")) {
|
||||||
|
binding.tagGender.setText("女");
|
||||||
|
} else {
|
||||||
|
binding.tagGender.setText("H");
|
||||||
|
}
|
||||||
|
binding.tagGender.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
binding.tagGender.setText("H");
|
||||||
|
binding.tagGender.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算并设置年龄标签
|
||||||
|
if (!TextUtils.isEmpty(birthday)) {
|
||||||
|
int age = calculateAge(birthday);
|
||||||
|
if (age > 0) {
|
||||||
|
binding.tagAge.setText(age + "岁");
|
||||||
|
binding.tagAge.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
binding.tagAge.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
binding.tagAge.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算并设置星座标签
|
||||||
|
if (!TextUtils.isEmpty(birthday)) {
|
||||||
|
String constellation = calculateConstellation(birthday);
|
||||||
|
if (!TextUtils.isEmpty(constellation)) {
|
||||||
|
binding.tagConstellation.setText(constellation);
|
||||||
|
binding.tagConstellation.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
binding.tagConstellation.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
binding.tagConstellation.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadProfileInfo() {
|
||||||
|
String name = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_NAME, "爱你");
|
||||||
|
String location = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_LOCATION, "广西");
|
||||||
|
String bio = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_BIO, null);
|
||||||
|
|
||||||
|
if (binding.profileInfoLine1 != null) {
|
||||||
|
binding.profileInfoLine1.setText("昵称:" + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binding.profileInfoLine2 != null) {
|
||||||
|
String locationText = !TextUtils.isEmpty(location) ? location : "广西";
|
||||||
|
binding.profileInfoLine2.setText("地区:" + locationText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binding.profileInfoLine3 != null) {
|
||||||
|
String bioText = (!TextUtils.isEmpty(bio) && !BIO_HINT_TEXT.equals(bio)) ? bio : "填写个人签名更容易获得关注";
|
||||||
|
binding.profileInfoLine3.setText("签名:" + bioText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calculateAge(String birthdayStr) {
|
||||||
|
try {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
||||||
|
Date birthDate = sdf.parse(birthdayStr);
|
||||||
|
if (birthDate == null) return 0;
|
||||||
|
|
||||||
|
Calendar birth = Calendar.getInstance();
|
||||||
|
birth.setTime(birthDate);
|
||||||
|
Calendar now = Calendar.getInstance();
|
||||||
|
|
||||||
|
int age = now.get(Calendar.YEAR) - birth.get(Calendar.YEAR);
|
||||||
|
if (now.get(Calendar.DAY_OF_YEAR) < birth.get(Calendar.DAY_OF_YEAR)) {
|
||||||
|
age--;
|
||||||
|
}
|
||||||
|
return age;
|
||||||
|
} catch (ParseException e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String calculateConstellation(String birthdayStr) {
|
||||||
|
try {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
||||||
|
Date birthDate = sdf.parse(birthdayStr);
|
||||||
|
if (birthDate == null) return "";
|
||||||
|
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTime(birthDate);
|
||||||
|
int month = cal.get(Calendar.MONTH) + 1; // Calendar.MONTH 从0开始
|
||||||
|
int day = cal.get(Calendar.DAY_OF_MONTH);
|
||||||
|
|
||||||
|
// 星座计算
|
||||||
|
if ((month == 3 && day >= 21) || (month == 4 && day <= 19)) {
|
||||||
|
return "白羊座";
|
||||||
|
} else if ((month == 4 && day >= 20) || (month == 5 && day <= 20)) {
|
||||||
|
return "金牛座";
|
||||||
|
} else if ((month == 5 && day >= 21) || (month == 6 && day <= 21)) {
|
||||||
|
return "双子座";
|
||||||
|
} else if ((month == 6 && day >= 22) || (month == 7 && day <= 22)) {
|
||||||
|
return "巨蟹座";
|
||||||
|
} else if ((month == 7 && day >= 23) || (month == 8 && day <= 22)) {
|
||||||
|
return "狮子座";
|
||||||
|
} else if ((month == 8 && day >= 23) || (month == 9 && day <= 22)) {
|
||||||
|
return "处女座";
|
||||||
|
} else if ((month == 9 && day >= 23) || (month == 10 && day <= 23)) {
|
||||||
|
return "天秤座";
|
||||||
|
} else if ((month == 10 && day >= 24) || (month == 11 && day <= 22)) {
|
||||||
|
return "天蝎座";
|
||||||
|
} else if ((month == 11 && day >= 23) || (month == 12 && day <= 21)) {
|
||||||
|
return "射手座";
|
||||||
|
} else if ((month == 12 && day >= 22) || (month == 1 && day <= 19)) {
|
||||||
|
return "摩羯座";
|
||||||
|
} else if ((month == 1 && day >= 20) || (month == 2 && day <= 18)) {
|
||||||
|
return "水瓶座";
|
||||||
|
} else if ((month == 2 && day >= 19) || (month == 3 && day <= 20)) {
|
||||||
|
return "双鱼座";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
} catch (ParseException e) {
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,17 @@ public class SearchActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private final List<Room> all = new ArrayList<>();
|
private final List<Room> all = new ArrayList<>();
|
||||||
|
|
||||||
|
private static final String EXTRA_SEARCH_QUERY = "search_query";
|
||||||
|
|
||||||
public static void start(Context context) {
|
public static void start(Context context) {
|
||||||
|
start(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void start(Context context, String searchQuery) {
|
||||||
Intent intent = new Intent(context, SearchActivity.class);
|
Intent intent = new Intent(context, SearchActivity.class);
|
||||||
|
if (searchQuery != null && !searchQuery.trim().isEmpty()) {
|
||||||
|
intent.putExtra(EXTRA_SEARCH_QUERY, searchQuery);
|
||||||
|
}
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,6 +49,13 @@ public class SearchActivity extends AppCompatActivity {
|
||||||
binding.backButton.setOnClickListener(v -> finish());
|
binding.backButton.setOnClickListener(v -> finish());
|
||||||
binding.cancelBtn.setOnClickListener(v -> finish());
|
binding.cancelBtn.setOnClickListener(v -> finish());
|
||||||
|
|
||||||
|
// 如果从Intent中获取到搜索关键词,自动填充到搜索框
|
||||||
|
String searchQuery = getIntent().getStringExtra(EXTRA_SEARCH_QUERY);
|
||||||
|
if (searchQuery != null && !searchQuery.trim().isEmpty()) {
|
||||||
|
binding.searchInput.setText(searchQuery);
|
||||||
|
binding.searchInput.setSelection(searchQuery.length());
|
||||||
|
}
|
||||||
|
|
||||||
binding.searchInput.requestFocus();
|
binding.searchInput.requestFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -232,9 +232,8 @@ public class TabPlaceholderActivity extends AppCompatActivity {
|
||||||
Toast.makeText(this, "点击:" + user.getName(), Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "点击:" + user.getName(), Toast.LENGTH_SHORT).show();
|
||||||
});
|
});
|
||||||
|
|
||||||
StaggeredGridLayoutManager glm = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
|
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
||||||
glm.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
|
binding.nearbyRecyclerView.setLayoutManager(layoutManager);
|
||||||
binding.nearbyRecyclerView.setLayoutManager(glm);
|
|
||||||
binding.nearbyRecyclerView.setAdapter(adapter);
|
binding.nearbyRecyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
adapter.submitList(buildNearbyDemoUsers(18));
|
adapter.submitList(buildNearbyDemoUsers(18));
|
||||||
|
|
@ -254,10 +253,12 @@ public class TabPlaceholderActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private List<NearbyUser> buildNearbyDemoUsers(int count) {
|
private List<NearbyUser> buildNearbyDemoUsers(int count) {
|
||||||
List<NearbyUser> list = new ArrayList<>();
|
List<NearbyUser> list = new ArrayList<>();
|
||||||
|
String[] names = {"小王", "小李", "安安", "小陈", "小美", "老张", "小七", "阿杰",
|
||||||
|
"小雨", "阿宁", "小星", "小林", "小杨", "小刘", "小赵", "小孙", "小周", "小吴"};
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
String id = "nearby-" + i;
|
String id = "user-" + i;
|
||||||
String name = "附近主播" + (i + 1);
|
String name = i < names.length ? names[i] : "用户" + (i + 1);
|
||||||
boolean live = i % 3 == 0;
|
boolean live = false; // 不再显示直播状态
|
||||||
String distanceText;
|
String distanceText;
|
||||||
if (i < 3) {
|
if (i < 3) {
|
||||||
distanceText = (300 + i * 120) + "m";
|
distanceText = (300 + i * 120) + "m";
|
||||||
|
|
@ -491,9 +492,7 @@ public class TabPlaceholderActivity extends AppCompatActivity {
|
||||||
Toast.makeText(this, "已发送好友请求:" + user.getName(), Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "已发送好友请求:" + user.getName(), Toast.LENGTH_SHORT).show();
|
||||||
});
|
});
|
||||||
|
|
||||||
StaggeredGridLayoutManager glm = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
|
binding.addFriendRecyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||||
glm.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
|
|
||||||
binding.addFriendRecyclerView.setLayoutManager(glm);
|
|
||||||
binding.addFriendRecyclerView.setAdapter(addFriendAdapter);
|
binding.addFriendRecyclerView.setAdapter(addFriendAdapter);
|
||||||
|
|
||||||
addFriendAllUsers.clear();
|
addFriendAllUsers.clear();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.example.livestreaming.databinding.ActivityTableGamesBinding;
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
|
public class TableGamesActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private ActivityTableGamesBinding binding;
|
||||||
|
|
||||||
|
public static void start(Context context) {
|
||||||
|
Intent intent = new Intent(context, TableGamesActivity.class);
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
binding = ActivityTableGamesBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
|
setupUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupUI() {
|
||||||
|
binding.backButton.setOnClickListener(v -> finish());
|
||||||
|
|
||||||
|
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
||||||
|
bottomNavigation.setSelectedItemId(R.id.nav_friends);
|
||||||
|
bottomNavigation.setOnItemSelectedListener(item -> {
|
||||||
|
int id = item.getItemId();
|
||||||
|
if (id == R.id.nav_home) {
|
||||||
|
startActivity(new Intent(this, MainActivity.class));
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_wish_tree) {
|
||||||
|
WishTreeActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_messages) {
|
||||||
|
MessagesActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_profile) {
|
||||||
|
ProfileActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
|
import com.google.android.material.badge.BadgeDrawable;
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
|
public class UnreadMessageManager {
|
||||||
|
|
||||||
|
private static final String PREFS_NAME = "unread_messages";
|
||||||
|
private static final String KEY_UNREAD_COUNT = "unread_count";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取总未读消息数量
|
||||||
|
*/
|
||||||
|
public static int getUnreadCount(Context context) {
|
||||||
|
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
||||||
|
return prefs.getInt(KEY_UNREAD_COUNT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置总未读消息数量
|
||||||
|
*/
|
||||||
|
public static void setUnreadCount(Context context, int count) {
|
||||||
|
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
||||||
|
prefs.edit().putInt(KEY_UNREAD_COUNT, Math.max(0, count)).apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 增加未读消息数量
|
||||||
|
*/
|
||||||
|
public static void incrementUnreadCount(Context context, int increment) {
|
||||||
|
int current = getUnreadCount(context);
|
||||||
|
setUnreadCount(context, current + increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 减少未读消息数量
|
||||||
|
*/
|
||||||
|
public static void decrementUnreadCount(Context context, int decrement) {
|
||||||
|
int current = getUnreadCount(context);
|
||||||
|
setUnreadCount(context, Math.max(0, current - decrement));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新底部导航栏的消息徽章
|
||||||
|
*/
|
||||||
|
public static void updateBadge(BottomNavigationView bottomNav) {
|
||||||
|
if (bottomNav == null) return;
|
||||||
|
|
||||||
|
Context context = bottomNav.getContext();
|
||||||
|
int unreadCount = getUnreadCount(context);
|
||||||
|
|
||||||
|
BadgeDrawable badge = bottomNav.getOrCreateBadge(R.id.nav_messages);
|
||||||
|
|
||||||
|
if (unreadCount > 0) {
|
||||||
|
badge.setVisible(true);
|
||||||
|
badge.setNumber(unreadCount);
|
||||||
|
// BadgeDrawable 会自动处理超过 99 的情况,显示 "99+"
|
||||||
|
} else {
|
||||||
|
badge.setVisible(false);
|
||||||
|
badge.clearNumber();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除未读消息数量(当用户进入消息页面时)
|
||||||
|
*/
|
||||||
|
public static void clearUnreadCount(Context context) {
|
||||||
|
setUnreadCount(context, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -58,6 +58,13 @@ public class UserProfileReadOnlyActivity extends AppCompatActivity {
|
||||||
binding.bio.setText(bio != null ? bio : "");
|
binding.bio.setText(bio != null ? bio : "");
|
||||||
binding.avatar.setImageResource(avatarRes);
|
binding.avatar.setImageResource(avatarRes);
|
||||||
|
|
||||||
|
// 设置头像点击放大功能
|
||||||
|
binding.avatar.setOnClickListener(v -> {
|
||||||
|
AvatarViewerDialog dialog = AvatarViewerDialog.create(this);
|
||||||
|
dialog.setAvatarResId(avatarRes);
|
||||||
|
dialog.show();
|
||||||
|
});
|
||||||
|
|
||||||
setupTabsAndWorks();
|
setupTabsAndWorks();
|
||||||
bindDemoStatsAndWorks(userId);
|
bindDemoStatsAndWorks(userId);
|
||||||
|
|
||||||
|
|
@ -86,8 +93,8 @@ public class UserProfileReadOnlyActivity extends AppCompatActivity {
|
||||||
|
|
||||||
if (binding.tabs.getTabCount() == 0) {
|
if (binding.tabs.getTabCount() == 0) {
|
||||||
binding.tabs.addTab(binding.tabs.newTab().setText("作品"));
|
binding.tabs.addTab(binding.tabs.newTab().setText("作品"));
|
||||||
binding.tabs.addTab(binding.tabs.newTab().setText("动态"));
|
binding.tabs.addTab(binding.tabs.newTab().setText("收藏"));
|
||||||
binding.tabs.addTab(binding.tabs.newTab().setText("资料"));
|
binding.tabs.addTab(binding.tabs.newTab().setText("赞过"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (worksAdapter == null) {
|
if (worksAdapter == null) {
|
||||||
|
|
@ -119,9 +126,10 @@ public class UserProfileReadOnlyActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private void showTab(int index) {
|
private void showTab(int index) {
|
||||||
if (binding == null) return;
|
if (binding == null) return;
|
||||||
|
// 标签页顺序:0-作品, 1-收藏, 2-赞过
|
||||||
binding.worksRecycler.setVisibility(index == 0 ? android.view.View.VISIBLE : android.view.View.GONE);
|
binding.worksRecycler.setVisibility(index == 0 ? android.view.View.VISIBLE : android.view.View.GONE);
|
||||||
binding.dynamicsPlaceholder.setVisibility(index == 1 ? android.view.View.VISIBLE : android.view.View.GONE);
|
binding.favoritesPlaceholder.setVisibility(index == 1 ? android.view.View.VISIBLE : android.view.View.GONE);
|
||||||
binding.profilePlaceholder.setVisibility(index == 2 ? android.view.View.VISIBLE : android.view.View.GONE);
|
binding.likedPlaceholder.setVisibility(index == 2 ? android.view.View.VISIBLE : android.view.View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindDemoStatsAndWorks(String userId) {
|
private void bindDemoStatsAndWorks(String userId) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.example.livestreaming;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.example.livestreaming.databinding.ActivityVoiceMatchBinding;
|
||||||
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
|
public class VoiceMatchActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private ActivityVoiceMatchBinding binding;
|
||||||
|
|
||||||
|
public static void start(Context context) {
|
||||||
|
Intent intent = new Intent(context, VoiceMatchActivity.class);
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
binding = ActivityVoiceMatchBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
|
setupUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupUI() {
|
||||||
|
binding.backButton.setOnClickListener(v -> finish());
|
||||||
|
|
||||||
|
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
|
||||||
|
bottomNavigation.setSelectedItemId(R.id.nav_friends);
|
||||||
|
bottomNavigation.setOnItemSelectedListener(item -> {
|
||||||
|
int id = item.getItemId();
|
||||||
|
if (id == R.id.nav_home) {
|
||||||
|
startActivity(new Intent(this, MainActivity.class));
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_wish_tree) {
|
||||||
|
WishTreeActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_messages) {
|
||||||
|
MessagesActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (id == R.id.nav_profile) {
|
||||||
|
ProfileActivity.start(this);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
android:viewportHeight="24">
|
android:viewportHeight="24">
|
||||||
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FFFFFF"
|
android:fillColor="#777777"
|
||||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM4.07,13h3.02c0.13,2.03 0.8,3.94 1.83,5.41C6.49,17.38 4.69,15.36 4.07,13zM7.09,11H4.07c0.62,-2.36 2.42,-4.38 4.85,-5.41C7.89,7.06 7.22,8.97 7.09,11zM11,19.93c-1.75,-0.31 -3.26,-2.62 -3.46,-5.93H11v5.93zM11,12H7.54C7.74,8.69 9.25,6.38 11,6.07V12zM19.93,11h-3.02c-0.13,-2.03 -0.8,-3.94 -1.83,-5.41C17.51,6.62 19.31,8.64 19.93,11zM13,6.07c1.75,0.31 3.26,2.62 3.46,5.93H13V6.07zM13,19.93V14h3.46c-0.2,3.31 -1.71,5.62 -3.46,5.93zM15.08,18.41c1.03,-1.47 1.7,-3.38 1.83,-5.41h3.02c-0.62,2.36 -2.42,4.38 -4.85,5.41z"/>
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM4.07,13h3.02c0.13,2.03 0.8,3.94 1.83,5.41C6.49,17.38 4.69,15.36 4.07,13zM7.09,11H4.07c0.62,-2.36 2.42,-4.38 4.85,-5.41C7.89,7.06 7.22,8.97 7.09,11zM11,19.93c-1.75,-0.31 -3.26,-2.62 -3.46,-5.93H11v5.93zM11,12H7.54C7.74,8.69 9.25,6.38 11,6.07V12zM19.93,11h-3.02c-0.13,-2.03 -0.8,-3.94 -1.83,-5.41C17.51,6.62 19.31,8.64 19.93,11zM13,6.07c1.75,0.31 3.26,2.62 3.46,5.93H13V6.07zM13,19.93V14h3.46c-0.2,3.31 -1.71,5.62 -3.46,5.93zM15.08,18.41c1.03,-1.47 1.7,-3.38 1.83,-5.41h3.02c-0.62,2.36 -2.42,4.38 -4.85,5.41z"/>
|
||||||
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
||||||
56
android-app/app/src/main/res/layout/activity_draw_guess.xml
Normal file
56
android-app/app/src/main/res/layout/activity_draw_guess.xml
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?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"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FFFFFF">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/backButton"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="返回"
|
||||||
|
android:src="@drawable/ic_arrow_back_24"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/titleText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="你画我猜"
|
||||||
|
android:textColor="#111111"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/backButton" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="发挥你的想象力,画出你的创意"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/titleText" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/bottomNavInclude"
|
||||||
|
layout="@layout/include_bottom_nav"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
@ -186,7 +186,7 @@
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:hint="生日(例如 2001-08-08)"
|
android:hint="生日"
|
||||||
app:boxBackgroundMode="filled"
|
app:boxBackgroundMode="filled"
|
||||||
app:boxBackgroundColor="@android:color/white"
|
app:boxBackgroundColor="@android:color/white"
|
||||||
app:boxCornerRadiusTopStart="14dp"
|
app:boxCornerRadiusTopStart="14dp"
|
||||||
|
|
@ -202,7 +202,13 @@
|
||||||
android:id="@+id/inputBirthday"
|
android:id="@+id/inputBirthday"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:maxLines="1" />
|
android:maxLines="1"
|
||||||
|
android:focusable="false"
|
||||||
|
android:focusableInTouchMode="false"
|
||||||
|
android:clickable="true"
|
||||||
|
android:cursorVisible="false"
|
||||||
|
android:enabled="true"
|
||||||
|
android:inputType="none" />
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
@ -211,7 +217,7 @@
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:hint="性别(男/女/保密)"
|
android:hint="性别"
|
||||||
app:boxBackgroundMode="filled"
|
app:boxBackgroundMode="filled"
|
||||||
app:boxBackgroundColor="@android:color/white"
|
app:boxBackgroundColor="@android:color/white"
|
||||||
app:boxCornerRadiusTopStart="14dp"
|
app:boxCornerRadiusTopStart="14dp"
|
||||||
|
|
@ -227,7 +233,10 @@
|
||||||
android:id="@+id/inputGender"
|
android:id="@+id/inputGender"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:maxLines="1" />
|
android:maxLines="1"
|
||||||
|
android:focusable="false"
|
||||||
|
android:clickable="true"
|
||||||
|
android:cursorVisible="false" />
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
@ -236,7 +245,7 @@
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:hint="所在地(例如 北京·朝阳)"
|
android:hint="所在地"
|
||||||
app:boxBackgroundMode="filled"
|
app:boxBackgroundMode="filled"
|
||||||
app:boxBackgroundColor="@android:color/white"
|
app:boxBackgroundColor="@android:color/white"
|
||||||
app:boxCornerRadiusTopStart="14dp"
|
app:boxCornerRadiusTopStart="14dp"
|
||||||
|
|
@ -252,7 +261,10 @@
|
||||||
android:id="@+id/inputLocation"
|
android:id="@+id/inputLocation"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:maxLines="1" />
|
android:maxLines="1"
|
||||||
|
android:focusable="false"
|
||||||
|
android:clickable="true"
|
||||||
|
android:cursorVisible="false" />
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
|
||||||
56
android-app/app/src/main/res/layout/activity_find_game.xml
Normal file
56
android-app/app/src/main/res/layout/activity_find_game.xml
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?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"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FFFFFF">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/backButton"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="返回"
|
||||||
|
android:src="@drawable/ic_arrow_back_24"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/titleText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="找人玩游戏"
|
||||||
|
android:textColor="#111111"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/backButton" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="找到志同道合的游戏伙伴,一起开黑"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/titleText" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/bottomNavInclude"
|
||||||
|
layout="@layout/include_bottom_nav"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
@ -4,7 +4,9 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@drawable/bg_fishpond_gradient"
|
android:background="@drawable/bg_fishpond_gradient"
|
||||||
android:paddingTop="18dp">
|
android:paddingTop="18dp"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:clipToPadding="false">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/titleText"
|
android:id="@+id/titleText"
|
||||||
|
|
@ -444,6 +446,7 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!--
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/floatingMenu"
|
android:id="@+id/floatingMenu"
|
||||||
android:layout_width="44dp"
|
android:layout_width="44dp"
|
||||||
|
|
@ -455,6 +458,7 @@
|
||||||
android:src="@drawable/ic_grid_24"
|
android:src="@drawable/ic_grid_24"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
-->
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
@ -472,7 +476,7 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/orbitContainer"
|
app:layout_constraintTop_toBottomOf="@id/orbitContainer"
|
||||||
app:layout_constraintBottom_toTopOf="@id/bottomAppBar">
|
app:layout_constraintBottom_toTopOf="@id/bottomNavInclude">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
@ -486,7 +490,6 @@
|
||||||
android:background="@drawable/bg_pill_left"
|
android:background="@drawable/bg_pill_left"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:foreground="?attr/selectableItemBackground"
|
|
||||||
android:paddingStart="14dp"
|
android:paddingStart="14dp"
|
||||||
android:paddingEnd="14dp"
|
android:paddingEnd="14dp"
|
||||||
app:layout_constraintEnd_toStartOf="@id/actionRight"
|
app:layout_constraintEnd_toStartOf="@id/actionRight"
|
||||||
|
|
@ -526,7 +529,6 @@
|
||||||
android:background="@drawable/bg_pill_right"
|
android:background="@drawable/bg_pill_right"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:foreground="?attr/selectableItemBackground"
|
|
||||||
android:paddingStart="14dp"
|
android:paddingStart="14dp"
|
||||||
android:paddingEnd="14dp"
|
android:paddingEnd="14dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?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"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FFF2F7">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/backButton"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="返回"
|
||||||
|
android:src="@drawable/ic_arrow_back_24"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/titleText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="心动信号"
|
||||||
|
android:textColor="#111111"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/backButton" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="发现让你心动的那个TA"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/titleText" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/bottomNavInclude"
|
||||||
|
layout="@layout/include_bottom_nav"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?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"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FFFFFF">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/backButton"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="返回"
|
||||||
|
android:src="@drawable/ic_arrow_back_24"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/titleText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="一起KTV"
|
||||||
|
android:textColor="#111111"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/backButton" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="和好友一起K歌,享受音乐时光"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/titleText" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/bottomNavInclude"
|
||||||
|
layout="@layout/include_bottom_nav"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
@ -7,7 +7,8 @@
|
||||||
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:fitsSystemWindows="false">
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/appBar"
|
android:id="@+id/appBar"
|
||||||
|
|
@ -39,9 +40,11 @@
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
app:tabIndicatorColor="@color/purple_500"
|
app:tabIndicatorColor="@color/purple_500"
|
||||||
app:tabIndicatorFullWidth="false"
|
app:tabIndicatorFullWidth="false"
|
||||||
app:tabSelectedTextColor="@color/purple_500"
|
app:tabIndicatorHeight="0dp"
|
||||||
|
app:tabSelectedTextColor="#666666"
|
||||||
app:tabTextColor="#666666"
|
app:tabTextColor="#666666"
|
||||||
app:layout_constraintEnd_toStartOf="@id/notificationButton"
|
app:tabRippleColor="@android:color/transparent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/avatarButton"
|
||||||
app:layout_constraintStart_toEndOf="@id/menuButton"
|
app:layout_constraintStart_toEndOf="@id/menuButton"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
|
@ -61,17 +64,6 @@
|
||||||
android:text="附近" />
|
android:text="附近" />
|
||||||
</com.google.android.material.tabs.TabLayout>
|
</com.google.android.material.tabs.TabLayout>
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/notificationButton"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:layout_marginEnd="14dp"
|
|
||||||
android:contentDescription="notification"
|
|
||||||
android:src="@drawable/ic_notifications_24"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/topTabs"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/avatarButton"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/topTabs" />
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/avatarButton"
|
android:id="@+id/avatarButton"
|
||||||
android:layout_width="28dp"
|
android:layout_width="28dp"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?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"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FFFFFF">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/backButton"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="返回"
|
||||||
|
android:src="@drawable/ic_arrow_back_24"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/titleText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="在线处对象"
|
||||||
|
android:textColor="#111111"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/backButton" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="寻找你的另一半,开启一段美好的缘分"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/titleText" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/bottomNavInclude"
|
||||||
|
layout="@layout/include_bottom_nav"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
56
android-app/app/src/main/res/layout/activity_peace_elite.xml
Normal file
56
android-app/app/src/main/res/layout/activity_peace_elite.xml
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?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"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FFFFFF">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/backButton"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="返回"
|
||||||
|
android:src="@drawable/ic_arrow_back_24"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/titleText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="和平精英"
|
||||||
|
android:textColor="#111111"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/backButton" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="组队开黑,一起吃鸡"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/titleText" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/bottomNavInclude"
|
||||||
|
layout="@layout/include_bottom_nav"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
@ -167,13 +167,6 @@
|
||||||
android:src="@drawable/ic_copy_24"
|
android:src="@drawable/ic_copy_24"
|
||||||
android:tint="#E6FFFFFF" />
|
android:tint="#E6FFFFFF" />
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="18dp"
|
|
||||||
android:layout_height="18dp"
|
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
android:src="@drawable/ic_grid_24"
|
|
||||||
android:tint="#E6FFFFFF" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
|
@ -228,7 +221,7 @@
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
app:layout_constraintEnd_toStartOf="@id/recordBtn"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
|
@ -264,18 +257,6 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/recordBtn"
|
|
||||||
android:layout_width="92dp"
|
|
||||||
android:layout_height="32dp"
|
|
||||||
android:background="@drawable/bg_gray_12"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="录制声音"
|
|
||||||
android:textColor="#111111"
|
|
||||||
android:textSize="12sp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/statsRow" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/bioText"
|
android:id="@+id/bioText"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
|
@ -299,6 +280,7 @@
|
||||||
app:layout_constraintTop_toBottomOf="@id/bioText">
|
app:layout_constraintTop_toBottomOf="@id/bioText">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/tagLocation"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:background="@drawable/bg_gray_12"
|
android:background="@drawable/bg_gray_12"
|
||||||
|
|
@ -310,6 +292,7 @@
|
||||||
android:textSize="11sp" />
|
android:textSize="11sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/tagGender"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
|
|
@ -322,6 +305,7 @@
|
||||||
android:textSize="11sp" />
|
android:textSize="11sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/tagAge"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
|
|
@ -334,6 +318,7 @@
|
||||||
android:textSize="11sp" />
|
android:textSize="11sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/tagConstellation"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
|
|
@ -346,6 +331,7 @@
|
||||||
android:textSize="11sp" />
|
android:textSize="11sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/tagPersonality"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
|
|
@ -601,11 +587,6 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="作品" />
|
android:text="作品" />
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabItem
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="赞过" />
|
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabItem
|
<com.google.android.material.tabs.TabItem
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
@ -614,7 +595,7 @@
|
||||||
<com.google.android.material.tabs.TabItem
|
<com.google.android.material.tabs.TabItem
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="资料" />
|
android:text="赞过" />
|
||||||
|
|
||||||
</com.google.android.material.tabs.TabLayout>
|
</com.google.android.material.tabs.TabLayout>
|
||||||
|
|
||||||
|
|
|
||||||
56
android-app/app/src/main/res/layout/activity_table_games.xml
Normal file
56
android-app/app/src/main/res/layout/activity_table_games.xml
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?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"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FFFFFF">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/backButton"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="返回"
|
||||||
|
android:src="@drawable/ic_arrow_back_24"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/titleText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="桌子游"
|
||||||
|
android:textColor="#111111"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/backButton" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="经典桌游,欢乐无限"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/titleText" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/bottomNavInclude"
|
||||||
|
layout="@layout/include_bottom_nav"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
@ -18,20 +18,109 @@
|
||||||
android:paddingTop="14dp"
|
android:paddingTop="14dp"
|
||||||
android:paddingBottom="16dp">
|
android:paddingBottom="16dp">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/guideline_start"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintGuide_percent="0.04" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/guideline_end"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintGuide_percent="0.96" />
|
||||||
|
|
||||||
|
<!-- 垂直方向的百分比参考线 (用于水平边距) -->
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/guideline_3pct_w"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintGuide_percent="0.03" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/guideline_3_5pct_w"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintGuide_percent="0.035" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/guideline_1pct_w"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintGuide_percent="0.01" />
|
||||||
|
|
||||||
|
<!-- 水平方向的百分比参考线 (用于垂直边距) -->
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/guideline_2_5pct_h"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintGuide_percent="0.025" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/guideline_3pct_h"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintGuide_percent="0.03" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/guideline_0_8pct_h"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintGuide_percent="0.008" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/guideline_2_8pct_h"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintGuide_percent="0.028" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/guideline_2pct_h"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintGuide_percent="0.02" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.Guideline
|
||||||
|
android:id="@+id/guideline_1_7pct_h"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintGuide_percent="0.017" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/backButton"
|
android:id="@+id/backButton"
|
||||||
android:layout_width="24dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="0dp"
|
||||||
android:contentDescription="back"
|
android:contentDescription="back"
|
||||||
android:src="@drawable/ic_arrow_back_24"
|
android:src="@drawable/ic_arrow_back_24"
|
||||||
|
app:layout_constraintDimensionRatio="1:1"
|
||||||
|
app:layout_constraintWidth_percent="0.06"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/space_title_margin"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintWidth_percent="0.03"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/backButton"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/backButton"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/backButton" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/title"
|
android:id="@+id/title"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text="TA的主页"
|
android:text="TA的主页"
|
||||||
|
|
@ -40,37 +129,71 @@
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/backButton"
|
app:layout_constraintBottom_toBottomOf="@id/backButton"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/backButton"
|
app:layout_constraintStart_toEndOf="@id/space_title_margin"
|
||||||
app:layout_constraintTop_toTopOf="@id/backButton" />
|
app:layout_constraintTop_toTopOf="@id/backButton" />
|
||||||
|
|
||||||
<ImageView
|
<Space
|
||||||
android:id="@+id/avatarRing"
|
android:id="@+id/space_avatar_margin_top"
|
||||||
android:layout_width="96dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="96dp"
|
android:layout_height="0dp"
|
||||||
android:layout_marginTop="18dp"
|
app:layout_constraintHeight_percent="0.025"
|
||||||
android:background="@drawable/bg_avatar_ring_pink"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/backButton" />
|
app:layout_constraintTop_toBottomOf="@id/backButton" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/avatarRing"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:background="@drawable/bg_avatar_ring_pink"
|
||||||
|
app:layout_constraintDimensionRatio="1:1"
|
||||||
|
app:layout_constraintWidth_percent="0.25"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/space_avatar_margin_top" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/space_avatar_margin"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintWidth_percent="0.01"
|
||||||
|
app:layout_constraintHeight_percent="0.01"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/avatarRing"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/avatarRing" />
|
||||||
|
|
||||||
<com.google.android.material.imageview.ShapeableImageView
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
android:id="@+id/avatar"
|
android:id="@+id/avatar"
|
||||||
android:layout_width="90dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="90dp"
|
android:layout_height="0dp"
|
||||||
android:layout_margin="3dp"
|
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
android:src="@drawable/wish_tree_checker_backup"
|
android:src="@drawable/wish_tree_checker_backup"
|
||||||
|
app:layout_constraintDimensionRatio="1:1"
|
||||||
|
app:layout_constraintWidth_percent="0.23"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/avatarRing"
|
app:layout_constraintBottom_toBottomOf="@id/avatarRing"
|
||||||
app:layout_constraintEnd_toEndOf="@id/avatarRing"
|
app:layout_constraintEnd_toEndOf="@id/avatarRing"
|
||||||
app:layout_constraintStart_toStartOf="@id/avatarRing"
|
app:layout_constraintStart_toEndOf="@id/space_avatar_margin"
|
||||||
app:layout_constraintTop_toTopOf="@id/avatarRing"
|
app:layout_constraintTop_toBottomOf="@id/space_avatar_margin"
|
||||||
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MaterialComponents.Circular" />
|
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MaterialComponents.Circular" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/space_name_margin_start"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintWidth_percent="0.035"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/avatarRing"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/backButton"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/backButton" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/space_name_margin_top"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintHeight_percent="0.03"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/space_name_margin_start"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/backButton" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/name"
|
android:id="@+id/name"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="14dp"
|
|
||||||
android:layout_marginTop="22dp"
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text="昵称"
|
android:text="昵称"
|
||||||
|
|
@ -78,61 +201,86 @@
|
||||||
android:textSize="20sp"
|
android:textSize="20sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/space_name_margin_start"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/space_name_margin_top" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/space_location_margin_start"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintWidth_percent="0.035"
|
||||||
app:layout_constraintStart_toEndOf="@id/avatarRing"
|
app:layout_constraintStart_toEndOf="@id/avatarRing"
|
||||||
app:layout_constraintTop_toBottomOf="@id/backButton" />
|
app:layout_constraintTop_toBottomOf="@id/name"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/name" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/space_location_margin_top"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintHeight_percent="0.008"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/space_location_margin_start"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/name" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/location"
|
android:id="@+id/location"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="14dp"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text="城市"
|
android:text="城市"
|
||||||
android:textColor="#666666"
|
android:textColor="#666666"
|
||||||
android:textSize="13sp"
|
android:textSize="13sp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/avatarRing"
|
app:layout_constraintStart_toEndOf="@id/space_location_margin_start"
|
||||||
app:layout_constraintTop_toBottomOf="@id/name" />
|
app:layout_constraintTop_toBottomOf="@id/space_location_margin_top" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/space_bio_margin_top"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintHeight_percent="0.025"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/avatarRing" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/bio"
|
android:id="@+id/bio"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="18dp"
|
|
||||||
android:text="签名"
|
android:text="签名"
|
||||||
android:textColor="#333333"
|
android:textColor="#333333"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/avatarRing" />
|
app:layout_constraintTop_toBottomOf="@id/space_bio_margin_top" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/space_addFriend_margin_top"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintHeight_percent="0.028"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/bio" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/addFriendButton"
|
android:id="@+id/addFriendButton"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="44dp"
|
android:layout_height="0dp"
|
||||||
android:layout_marginTop="20dp"
|
|
||||||
android:background="@drawable/bg_purple_999"
|
android:background="@drawable/bg_purple_999"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="加好友"
|
android:text="加好友"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:textSize="15sp"
|
android:textSize="15sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintHeight_percent="0.055"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/bio" />
|
app:layout_constraintTop_toBottomOf="@id/space_addFriend_margin_top" />
|
||||||
|
|
||||||
<TextView
|
<Space
|
||||||
android:id="@+id/readOnlyHint"
|
android:id="@+id/space_statsRow_margin_top"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:layout_marginTop="10dp"
|
app:layout_constraintHeight_percent="0.025"
|
||||||
android:text="仅可查看对方资料,不能编辑"
|
|
||||||
android:textColor="#999999"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:gravity="center"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/addFriendButton" />
|
app:layout_constraintTop_toBottomOf="@id/addFriendButton" />
|
||||||
|
|
||||||
|
|
@ -140,10 +288,9 @@
|
||||||
android:id="@+id/statsRow"
|
android:id="@+id/statsRow"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="18dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/readOnlyHint">
|
app:layout_constraintTop_toBottomOf="@id/space_statsRow_margin_top">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/statWorks"
|
android:id="@+id/statWorks"
|
||||||
|
|
@ -263,51 +410,80 @@
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/space_tabs_margin_top"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintHeight_percent="0.02"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/statsRow" />
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
<com.google.android.material.tabs.TabLayout
|
||||||
android:id="@+id/tabs"
|
android:id="@+id/tabs"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="14dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/statsRow" />
|
app:layout_constraintTop_toBottomOf="@id/space_tabs_margin_top" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/space_worksRecycler_margin_top"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintHeight_percent="0.017"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tabs" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/worksRecycler"
|
android:id="@+id/worksRecycler"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:nestedScrollingEnabled="false"
|
android:nestedScrollingEnabled="false"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/space_worksRecycler_margin_top" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/space_favoritesPlaceholder_margin_top"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintHeight_percent="0.025"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tabs" />
|
app:layout_constraintTop_toBottomOf="@id/tabs" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/dynamicsPlaceholder"
|
android:id="@+id/favoritesPlaceholder"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="18dp"
|
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="暂无动态"
|
android:text="收藏夹空空的"
|
||||||
android:textColor="#999999"
|
android:textColor="#999999"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/space_favoritesPlaceholder_margin_top" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/space_likedPlaceholder_margin_top"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintHeight_percent="0.025"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tabs" />
|
app:layout_constraintTop_toBottomOf="@id/tabs" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/profilePlaceholder"
|
android:id="@+id/likedPlaceholder"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="18dp"
|
android:gravity="center"
|
||||||
android:text="资料\n\n生日:--\n性别:--\n所在地:--"
|
android:text="还没有赞过的内容"
|
||||||
android:textColor="#333333"
|
android:textColor="#999999"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tabs" />
|
app:layout_constraintTop_toBottomOf="@id/space_likedPlaceholder_margin_top" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
|
||||||
56
android-app/app/src/main/res/layout/activity_voice_match.xml
Normal file
56
android-app/app/src/main/res/layout/activity_voice_match.xml
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?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"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#F7F2FF">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/backButton"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="返回"
|
||||||
|
android:src="@drawable/ic_arrow_back_24"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/titleText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="语音匹配"
|
||||||
|
android:textColor="#111111"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/backButton" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="通过语音快速匹配志同道合的朋友"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/titleText" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/bottomNavInclude"
|
||||||
|
layout="@layout/include_bottom_nav"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
107
android-app/app/src/main/res/layout/bottom_sheet_date_picker.xml
Normal file
107
android-app/app/src/main/res/layout/bottom_sheet_date_picker.xml
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@drawable/bg_white_16"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="选择生日"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#111111"
|
||||||
|
android:paddingBottom="16dp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<NumberPicker
|
||||||
|
android:id="@+id/yearPicker"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<NumberPicker
|
||||||
|
android:id="@+id/monthPicker"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<NumberPicker
|
||||||
|
android:id="@+id/dayPicker"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:gravity="end">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/cancelButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="44dp"
|
||||||
|
android:paddingStart="24dp"
|
||||||
|
android:paddingEnd="24dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="取消"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:layout_marginEnd="12dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/confirmButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="44dp"
|
||||||
|
android:paddingStart="24dp"
|
||||||
|
android:paddingEnd="24dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="确定"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:background="@drawable/bg_purple_999" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@drawable/bg_white_16"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="选择地址"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#111111"
|
||||||
|
android:paddingBottom="16dp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="400dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/provinceRecycler"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginEnd="8dp" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/cityRecycler"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginEnd="4dp" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/districtRecycler"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="8dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:gravity="end">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/cancelButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="44dp"
|
||||||
|
android:paddingStart="24dp"
|
||||||
|
android:paddingEnd="24dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="取消"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:layout_marginEnd="12dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/confirmButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="44dp"
|
||||||
|
android:paddingStart="24dp"
|
||||||
|
android:paddingEnd="24dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="确定"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:background="@drawable/bg_purple_999" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@drawable/bg_white_16"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="选择地址"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#111111"
|
||||||
|
android:paddingBottom="16dp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="省份"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:paddingEnd="8dp" />
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/provinceSpinner"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_weight="2"
|
||||||
|
android:background="@drawable/bg_gray_12" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_marginTop="12dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="城市"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:paddingEnd="8dp" />
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/citySpinner"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_weight="2"
|
||||||
|
android:background="@drawable/bg_gray_12" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:gravity="end">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/cancelButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="44dp"
|
||||||
|
android:paddingStart="24dp"
|
||||||
|
android:paddingEnd="24dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="取消"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:layout_marginEnd="12dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/confirmButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="44dp"
|
||||||
|
android:paddingStart="24dp"
|
||||||
|
android:paddingEnd="24dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="确定"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:background="@drawable/bg_purple_999" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
20
android-app/app/src/main/res/layout/dialog_avatar_viewer.xml
Normal file
20
android-app/app/src/main/res/layout/dialog_avatar_viewer.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/rootLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#000000"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/avatarImageView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:contentDescription="头像预览" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
@ -1,26 +1,20 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<com.google.android.material.bottomappbar.BottomAppBar xmlns:android="http://schemas.android.com/apk/res/android"
|
<com.google.android.material.bottomnavigation.BottomNavigationView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/bottomAppBar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingStart="0dp"
|
|
||||||
android:paddingEnd="0dp"
|
|
||||||
app:backgroundTint="@android:color/white"
|
|
||||||
app:contentInsetStart="0dp"
|
|
||||||
app:contentInsetEnd="0dp"
|
|
||||||
app:contentInsetStartWithNavigation="0dp"
|
|
||||||
app:hideOnScroll="false">
|
|
||||||
|
|
||||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
|
||||||
android:id="@+id/bottomNavigation"
|
android:id="@+id/bottomNavigation"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="48dp"
|
||||||
|
android:minHeight="48dp"
|
||||||
android:background="@android:color/white"
|
android:background="@android:color/white"
|
||||||
|
android:paddingTop="2dp"
|
||||||
|
android:paddingBottom="2dp"
|
||||||
|
android:fitsSystemWindows="false"
|
||||||
|
android:elevation="8dp"
|
||||||
app:itemIconTint="@color/bottom_nav_item_color"
|
app:itemIconTint="@color/bottom_nav_item_color"
|
||||||
app:itemTextColor="@color/bottom_nav_item_color"
|
app:itemTextColor="@color/bottom_nav_item_color"
|
||||||
|
app:itemIconSize="22dp"
|
||||||
|
app:itemTextAppearanceActive="@style/BottomNavigationView.TextAppearance"
|
||||||
|
app:itemTextAppearanceInactive="@style/BottomNavigationView.TextAppearance"
|
||||||
app:labelVisibilityMode="labeled"
|
app:labelVisibilityMode="labeled"
|
||||||
app:menu="@menu/bottom_nav_main" />
|
app:menu="@menu/bottom_nav_main" />
|
||||||
|
|
||||||
</com.google.android.material.bottomappbar.BottomAppBar>
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,9 @@
|
||||||
android:id="@+id/avatar"
|
android:id="@+id/avatar"
|
||||||
android:layout_width="44dp"
|
android:layout_width="44dp"
|
||||||
android:layout_height="44dp"
|
android:layout_height="44dp"
|
||||||
android:background="@drawable/bg_avatar_circle"
|
android:background="@drawable/bg_avatar_circle_transparent"
|
||||||
android:padding="6dp"
|
android:clipToOutline="true"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
android:src="@drawable/ic_account_circle_24"
|
android:src="@drawable/ic_account_circle_24"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,9 @@
|
||||||
android:id="@+id/avatarView"
|
android:id="@+id/avatarView"
|
||||||
android:layout_width="34dp"
|
android:layout_width="34dp"
|
||||||
android:layout_height="34dp"
|
android:layout_height="34dp"
|
||||||
android:background="@drawable/bg_avatar_circle"
|
android:background="@drawable/bg_avatar_circle_transparent"
|
||||||
android:padding="5dp"
|
android:clipToOutline="true"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
android:src="@drawable/ic_account_circle_24"
|
android:src="@drawable/ic_account_circle_24"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,9 @@
|
||||||
android:id="@+id/avatarView"
|
android:id="@+id/avatarView"
|
||||||
android:layout_width="34dp"
|
android:layout_width="34dp"
|
||||||
android:layout_height="34dp"
|
android:layout_height="34dp"
|
||||||
android:background="@drawable/bg_avatar_circle"
|
android:background="@drawable/bg_avatar_circle_transparent"
|
||||||
android:padding="5dp"
|
android:clipToOutline="true"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
android:src="@drawable/ic_account_circle_24"
|
android:src="@drawable/ic_account_circle_24"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
|
||||||
|
|
@ -1,78 +1,78 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="72dp"
|
||||||
android:layout_margin="6dp"
|
android:background="@android:color/white"
|
||||||
app:cardCornerRadius="14dp"
|
android:paddingStart="16dp"
|
||||||
app:cardElevation="0dp"
|
android:paddingEnd="16dp">
|
||||||
app:strokeColor="#14000000"
|
|
||||||
app:strokeWidth="1dp">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="12dp">
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/avatarImage"
|
android:id="@+id/avatarImage"
|
||||||
android:layout_width="0dp"
|
android:layout_width="44dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="44dp"
|
||||||
android:background="#0A000000"
|
android:background="@drawable/bg_avatar_circle"
|
||||||
|
android:padding="6dp"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
android:src="@drawable/ic_account_circle_24"
|
android:src="@drawable/ic_account_circle_24"
|
||||||
app:layout_constraintDimensionRatio="1:1"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/liveBadge"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:background="@drawable/live_badge_background"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:paddingTop="3dp"
|
|
||||||
android:paddingBottom="3dp"
|
|
||||||
android:text="LIVE"
|
|
||||||
android:textColor="@android:color/white"
|
|
||||||
android:textSize="10sp"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_constraintStart_toStartOf="@id/avatarImage"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/avatarImage" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/userName"
|
android:id="@+id/userName"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="10dp"
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginEnd="12dp"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text="附近主播"
|
android:text="用户昵称"
|
||||||
android:textColor="#111111"
|
android:textColor="#111111"
|
||||||
android:textSize="13sp"
|
android:textSize="15sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toStartOf="@id/addButton"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toEndOf="@id/avatarImage"
|
||||||
app:layout_constraintTop_toBottomOf="@id/avatarImage" />
|
app:layout_constraintTop_toTopOf="@id/avatarImage" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/distanceText"
|
android:id="@+id/distanceText"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_marginEnd="12dp"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text="1.2km"
|
android:text="距离 1.2km"
|
||||||
android:textColor="#666666"
|
android:textColor="#666666"
|
||||||
android:textSize="12sp"
|
android:textSize="13sp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toStartOf="@id/addButton"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toEndOf="@id/avatarImage"
|
||||||
app:layout_constraintTop_toBottomOf="@id/userName" />
|
app:layout_constraintTop_toBottomOf="@id/userName" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
<TextView
|
||||||
|
android:id="@+id/addButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:background="@drawable/bg_purple_999"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:text="添加"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
<View
|
||||||
|
android:id="@+id/divider"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="#0F000000"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/avatarImage" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
||||||
|
|
@ -34,4 +34,9 @@
|
||||||
<item name="cornerSize">50%</item>
|
<item name="cornerSize">50%</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<!-- 底部导航栏文字样式 -->
|
||||||
|
<style name="BottomNavigationView.TextAppearance" parent="TextAppearance.AppCompat">
|
||||||
|
<item name="android:textSize">10sp</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user