diff --git a/LLRiseTabBarDemo/app/build.gradle b/LLRiseTabBarDemo/app/build.gradle index dac0ed5..b27a390 100644 --- a/LLRiseTabBarDemo/app/build.gradle +++ b/LLRiseTabBarDemo/app/build.gradle @@ -39,6 +39,10 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') testImplementation 'junit:junit:4.13.2' + implementation 'com.github.bumptech.glide:glide:4.15.1' + implementation 'com.google.android.material:material:1.9.0' + implementation 'androidx.recyclerview:recyclerview:1.3.1' + // AndroidX 依赖 implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.9.0' diff --git a/LLRiseTabBarDemo/app/src/main/AndroidManifest.xml b/LLRiseTabBarDemo/app/src/main/AndroidManifest.xml index 4854606..6907bda 100644 --- a/LLRiseTabBarDemo/app/src/main/AndroidManifest.xml +++ b/LLRiseTabBarDemo/app/src/main/AndroidManifest.xml @@ -1,7 +1,10 @@ + + + imageUris; + private static final int MAX_IMAGES = 9; + + public ImageAdapter(Context context, List imageUris) { + this.context = context; + this.imageUris = imageUris; + } + + @Override + public int getCount() { + return Math.min(imageUris.size() + 1, MAX_IMAGES); + } + + @Override + public Object getItem(int position) { + if (position < imageUris.size()) { + return imageUris.get(position); + } + return null; + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ViewHolder holder; + if (convertView == null) { + convertView = LayoutInflater.from(context).inflate(R.layout.item_image, parent, false); + holder = new ViewHolder(); + holder.imageView = convertView.findViewById(R.id.imageView); + holder.deleteButton = convertView.findViewById(R.id.btnDelete); + convertView.setTag(holder); + } else { + holder = (ViewHolder) convertView.getTag(); + } + + if (position < imageUris.size()) { + // 显示已选择的图片 + Uri imageUri = imageUris.get(position); + Glide.with(context) + .load(imageUri) + .placeholder(android.R.drawable.ic_menu_gallery) // 使用系统图标作为占位符 + .into(holder.imageView); + + holder.deleteButton.setVisibility(View.VISIBLE); + holder.deleteButton.setOnClickListener(v -> { + imageUris.remove(position); + notifyDataSetChanged(); + }); + } else { + // 显示添加按钮 + holder.imageView.setImageResource(android.R.drawable.ic_input_add); // 使用系统图标 + holder.deleteButton.setVisibility(View.GONE); + } + + return convertView; + } + + static class ViewHolder { + ImageView imageView; + ImageView deleteButton; + } +} \ No newline at end of file diff --git a/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/activity/MainActivity.java b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/activity/MainActivity.java index ed589b0..20b0ccb 100644 --- a/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/activity/MainActivity.java +++ b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/activity/MainActivity.java @@ -7,6 +7,11 @@ import android.widget.Toast; // 改为 AndroidX import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.FragmentTransaction; + +import com.startsmake.llrisetabbardemo.fragment.PublishFragment; +import com.startsmake.llrisetabbardemo.fragment.HomeFragment; + import com.startsmake.llrisetabbardemo.R; import com.startsmake.llrisetabbardemo.fragment.CityFragment; import com.startsmake.llrisetabbardemo.fragment.HomeFragment; @@ -35,6 +40,9 @@ public class MainActivity extends AppCompatActivity { mNavigateTabBar.addTab(HomeFragment.class, new MainNavigateTabBar.TabParam(R.mipmap.comui_tab_home, R.mipmap.comui_tab_home_selected, TAG_PAGE_HOME)); mNavigateTabBar.addTab(CityFragment.class, new MainNavigateTabBar.TabParam(R.mipmap.comui_tab_city, R.mipmap.comui_tab_city_selected, TAG_PAGE_CITY)); + + mNavigateTabBar.addTab(null, new MainNavigateTabBar.TabParam(R.mipmap.comui_tab_post, R.mipmap.comui_tab_post, TAG_PAGE_PUBLISH)); + mNavigateTabBar.addTab(null, new MainNavigateTabBar.TabParam(0, 0, TAG_PAGE_PUBLISH)); mNavigateTabBar.addTab(MessageFragment.class, new MainNavigateTabBar.TabParam(R.mipmap.comui_tab_message, R.mipmap.comui_tab_message_selected, TAG_PAGE_MESSAGE)); mNavigateTabBar.addTab(PersonFragment.class, new MainNavigateTabBar.TabParam(R.mipmap.comui_tab_person, R.mipmap.comui_tab_person_selected, TAG_PAGE_PERSON)); @@ -46,7 +54,31 @@ public class MainActivity extends AppCompatActivity { mNavigateTabBar.onSaveInstanceState(outState); } + // 发布按钮点击事件 public void onClickPublish(View v) { - Toast.makeText(this, "发布", Toast.LENGTH_LONG).show(); + // 切换到发布Fragment + switchToPublishFragment(); + } + + // 切换到发布Fragment + public void switchToPublishFragment() { + PublishFragment publishFragment = new PublishFragment(); + + // 使用FragmentTransaction来显示发布页面 + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + + // 替换当前显示的Fragment + transaction.replace(R.id.container, publishFragment, "PublishFragment"); + transaction.addToBackStack("publish"); // 允许用户按返回键回到之前的Fragment + transaction.commit(); + } + + // 切换回首页Fragment + public void switchToHomeFragment() { + // 返回到首页 + getSupportFragmentManager().popBackStackImmediate(); + + // 确保底部导航栏选中首页 + mNavigateTabBar.setCurrentSelectedTab(0); } } \ No newline at end of file diff --git a/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/HomeFragment.java b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/HomeFragment.java index e856bcd..766ee01 100644 --- a/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/HomeFragment.java +++ b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/HomeFragment.java @@ -5,6 +5,8 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Button; + // 改为 AndroidX import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; @@ -21,6 +23,8 @@ public class HomeFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + + return inflater.inflate(R.layout.fragment_home, container, false); } } \ No newline at end of file diff --git a/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/PublishFragment.java b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/PublishFragment.java new file mode 100644 index 0000000..c6152c8 --- /dev/null +++ b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/PublishFragment.java @@ -0,0 +1,204 @@ +package com.startsmake.llrisetabbardemo.fragment; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.Spinner; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import com.startsmake.llrisetabbardemo.R; +import com.startsmake.llrisetabbardemo.activity.MainActivity; +import com.startsmake.llrisetabbardemo.adapter.ImageAdapter; + +import com.startsmake.llrisetabbardemo.model.Item; + +import java.util.ArrayList; +import java.util.List; + +public class PublishFragment extends Fragment { + + private static final int REQUEST_CODE_PICK_IMAGES = 1001; + private static final int MAX_IMAGE_COUNT = 9; + + private EditText etTitle, etDescription, etPrice, etContact; + private Spinner spinnerCategory, spinnerLocation; + private GridView gridViewImages; + private Button btnPublish; + + private ImageAdapter imageAdapter; + private List selectedImages = new ArrayList<>(); + + public PublishFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_publish, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + initViews(view); + setupSpinners(); + setupImageGrid(); + setupClickListeners(); + } + + private void initViews(View view) { + etTitle = view.findViewById(R.id.etTitle); + etDescription = view.findViewById(R.id.etDescription); + etPrice = view.findViewById(R.id.etPrice); + etContact = view.findViewById(R.id.etContact); + spinnerCategory = view.findViewById(R.id.spinnerCategory); + spinnerLocation = view.findViewById(R.id.spinnerLocation); + gridViewImages = view.findViewById(R.id.gridViewImages); + btnPublish = view.findViewById(R.id.btnPublish); + } + + private void setupSpinners() { + String[] categories = {"数码产品", "服装鞋帽", "家居日用", "图书文具", "美妆个护", "运动户外", "其他"}; + ArrayAdapter categoryAdapter = new ArrayAdapter<>( + requireContext(), android.R.layout.simple_spinner_item, categories); + categoryAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinnerCategory.setAdapter(categoryAdapter); + + String[] locations = {"北京", "上海", "广州", "深圳", "杭州", "成都", "武汉", "其他"}; + ArrayAdapter locationAdapter = new ArrayAdapter<>( + requireContext(), android.R.layout.simple_spinner_item, locations); + locationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinnerLocation.setAdapter(locationAdapter); + } + + private void setupImageGrid() { + imageAdapter = new ImageAdapter(requireContext(), selectedImages); + gridViewImages.setAdapter(imageAdapter); + } + + private void setupClickListeners() { + gridViewImages.setOnItemClickListener((parent, view, position, id) -> { + if (position == selectedImages.size() && selectedImages.size() < MAX_IMAGE_COUNT) { + openImagePicker(); + } + }); + + btnPublish.setOnClickListener(v -> publishItem()); + } + + private void openImagePicker() { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.setType("image/*"); + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); + startActivityForResult(Intent.createChooser(intent, "选择图片"), REQUEST_CODE_PICK_IMAGES); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + if (requestCode == REQUEST_CODE_PICK_IMAGES && resultCode == Activity.RESULT_OK) { + if (data != null) { + if (data.getClipData() != null) { + int count = Math.min(data.getClipData().getItemCount(), + MAX_IMAGE_COUNT - selectedImages.size()); + for (int i = 0; i < count; i++) { + Uri imageUri = data.getClipData().getItemAt(i).getUri(); + selectedImages.add(imageUri); + } + } else if (data.getData() != null) { + selectedImages.add(data.getData()); + } + imageAdapter.notifyDataSetChanged(); + } + } + } + + private void publishItem() { + String title = etTitle.getText().toString().trim(); + String description = etDescription.getText().toString().trim(); + String priceStr = etPrice.getText().toString().trim(); + String contact = etContact.getText().toString().trim(); + + if (title.isEmpty()) { + Toast.makeText(requireContext(), "请输入商品标题", Toast.LENGTH_SHORT).show(); + return; + } + + if (description.isEmpty()) { + Toast.makeText(requireContext(), "请输入商品描述", Toast.LENGTH_SHORT).show(); + return; + } + + if (priceStr.isEmpty()) { + Toast.makeText(requireContext(), "请输入商品价格", Toast.LENGTH_SHORT).show(); + return; + } + + if (contact.isEmpty()) { + Toast.makeText(requireContext(), "请输入联系方式", Toast.LENGTH_SHORT).show(); + return; + } + + if (selectedImages.isEmpty()) { + Toast.makeText(requireContext(), "请至少上传一张图片", Toast.LENGTH_SHORT).show(); + return; + } + + try { + double price = Double.parseDouble(priceStr); + if (price <= 0) { + Toast.makeText(requireContext(), "价格必须大于0", Toast.LENGTH_SHORT).show(); + return; + } + + // 创建物品对象 + Item item = new Item(); + item.setTitle(title); + item.setDescription(description); + item.setPrice(price); + item.setContact(contact); + item.setCategory(spinnerCategory.getSelectedItem().toString()); + item.setLocation(spinnerLocation.getSelectedItem().toString()); + item.setPublishTime(System.currentTimeMillis()); + item.setUserId("user_" + System.currentTimeMillis()); + + // 发布成功 + Toast.makeText(requireContext(), "发布成功!", Toast.LENGTH_SHORT).show(); + clearForm(); + + // 发布完成后自动返回首页 + if (getActivity() instanceof MainActivity) { + ((MainActivity) getActivity()).switchToHomeFragment(); + } + + } catch (NumberFormatException e) { + Toast.makeText(requireContext(), "请输入有效的价格", Toast.LENGTH_SHORT).show(); + } + } + + private void clearForm() { + etTitle.setText(""); + etDescription.setText(""); + etPrice.setText(""); + etContact.setText(""); + selectedImages.clear(); + imageAdapter.notifyDataSetChanged(); + spinnerCategory.setSelection(0); + spinnerLocation.setSelection(0); + } +} \ No newline at end of file diff --git a/LLRiseTabBarDemo/app/src/main/java/model/Item.java b/LLRiseTabBarDemo/app/src/main/java/model/Item.java new file mode 100644 index 0000000..d5e58bf --- /dev/null +++ b/LLRiseTabBarDemo/app/src/main/java/model/Item.java @@ -0,0 +1,53 @@ +package com.startsmake.llrisetabbardemo.model; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class Item implements Serializable { + private String id; + private String title; + private String description; + private double price; + private List imageUrls; + private String category; + private String location; + private String contact; + private long publishTime; + private String userId; + + public Item() { + imageUrls = new ArrayList<>(); + } + + // Getters and Setters + public String getId() { return id; } + public void setId(String id) { this.id = id; } + + public String getTitle() { return title; } + public void setTitle(String title) { this.title = title; } + + public String getDescription() { return description; } + public void setDescription(String description) { this.description = description; } + + public double getPrice() { return price; } + public void setPrice(double price) { this.price = price; } + + public List getImageUrls() { return imageUrls; } + public void setImageUrls(List imageUrls) { this.imageUrls = imageUrls; } + + public String getCategory() { return category; } + public void setCategory(String category) { this.category = category; } + + public String getLocation() { return location; } + public void setLocation(String location) { this.location = location; } + + public String getContact() { return contact; } + public void setContact(String contact) { this.contact = contact; } + + public long getPublishTime() { return publishTime; } + public void setPublishTime(long publishTime) { this.publishTime = publishTime; } + + public String getUserId() { return userId; } + public void setUserId(String userId) { this.userId = userId; } +} \ No newline at end of file diff --git a/LLRiseTabBarDemo/app/src/main/res/drawable/bg_delete_button.xml b/LLRiseTabBarDemo/app/src/main/res/drawable/bg_delete_button.xml new file mode 100644 index 0000000..f587175 --- /dev/null +++ b/LLRiseTabBarDemo/app/src/main/res/drawable/bg_delete_button.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/LLRiseTabBarDemo/app/src/main/res/drawable/bg_edittext.xml b/LLRiseTabBarDemo/app/src/main/res/drawable/bg_edittext.xml new file mode 100644 index 0000000..8bf7e47 --- /dev/null +++ b/LLRiseTabBarDemo/app/src/main/res/drawable/bg_edittext.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/LLRiseTabBarDemo/app/src/main/res/drawable/bg_image_border.xml b/LLRiseTabBarDemo/app/src/main/res/drawable/bg_image_border.xml new file mode 100644 index 0000000..01788a4 --- /dev/null +++ b/LLRiseTabBarDemo/app/src/main/res/drawable/bg_image_border.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/LLRiseTabBarDemo/app/src/main/res/drawable/rounded_background1.xml b/LLRiseTabBarDemo/app/src/main/res/drawable/rounded_background1.xml new file mode 100644 index 0000000..873c0bc --- /dev/null +++ b/LLRiseTabBarDemo/app/src/main/res/drawable/rounded_background1.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LLRiseTabBarDemo/app/src/main/res/layout/activity_main.xml b/LLRiseTabBarDemo/app/src/main/res/layout/activity_main.xml index 179e938..a3eb562 100644 --- a/LLRiseTabBarDemo/app/src/main/res/layout/activity_main.xml +++ b/LLRiseTabBarDemo/app/src/main/res/layout/activity_main.xml @@ -44,4 +44,25 @@ android:onClick="onClickPublish" android:src="@mipmap/comui_tab_post"/> + + + + + + + + + + + + + + diff --git a/LLRiseTabBarDemo/app/src/main/res/layout/fragment_home.xml b/LLRiseTabBarDemo/app/src/main/res/layout/fragment_home.xml index d081710..002f9c0 100644 --- a/LLRiseTabBarDemo/app/src/main/res/layout/fragment_home.xml +++ b/LLRiseTabBarDemo/app/src/main/res/layout/fragment_home.xml @@ -1,14 +1,30 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LLRiseTabBarDemo/app/src/main/res/layout/fragment_publish.xml b/LLRiseTabBarDemo/app/src/main/res/layout/fragment_publish.xml new file mode 100644 index 0000000..f041669 --- /dev/null +++ b/LLRiseTabBarDemo/app/src/main/res/layout/fragment_publish.xml @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +