- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在开发一个 Android 项目,在该项目中,我使用“SuperSlim”框架来创建 Notes(自定义类)的 GridView 以及要显示的数据。数据库中的注释与部分(自定义类)具有多对一的关系。而 Sections 又与 Canvas 具有多对一的关系。
部分的所有信息,注释都是作为列表从服务器动态检索的。
现在我可以显示部分的 GridView ,并将文本信息(如部分名称等)放入网格中。出于测试目的,我还插入了从笔记中静态检索的文本。我是 Android 编程的新手,所以如果代码看起来乱七八糟,请不要介意。
现在这些是我面临的问题:
1) 如何显示部分网格,在显示的每个部分中,我想显示一个注释网格。由于存在一对多关系,因此每个部分可以有多个注释。这是我的主要问题。
2) 通过显示上面的内容,我想保持 SectionName 字段可编辑,并且我有一个 REST 方法可以用来编辑 Section-name,但我也需要 section-id。单击即可使用,我想维护它。
3) Section 中显示的笔记网格应该是可点击的,这样我以后可以打开类似于 Modal 的东西,这样用户就可以阅读整个笔记并进行编辑。
下面的截图显示了我目前的情况:
左侧移动是网格部分列表的原始外观。我对其进行了修改,以显示更多信息,仅用于测试,并使用 SuperSlim 更正确地添加信息。
请注意,目前在代码中,我正在为硬编码部分静态调用 NotesList 方法。这是不希望的。最后代码:
组节 Activity :
public class GroupSectionActivity extends ActionBarActivity {
private SectionServiceImpl sectionService = new SectionServiceImpl();
private static volatile List<RestSection> restSectionList = new ArrayList<>();
private static volatile Long groupAccountId;
private static volatile Integer canvasid;
static final String msectionname = "msectionname";
static final String msectionid = "msectionid";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_section_activity);
Bundle extras = getIntent().getExtras();
if (extras != null) {
groupAccountId = extras.getLong("groupid");
canvasid = extras.getInt("canvasid");
}
if(savedInstanceState == null){
getFragmentManager().beginTransaction().add(R.id.container, new NoteFragments(), "msectionname").commit();
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if(toolbar!=null){
setSupportActionBar(toolbar);
}
restSectionList = this.sectionService.getSectionByCanvas(canvasid);
ArrayList<HashMap<String, String>> restSectionArrayList = new ArrayList<HashMap<String, String>>();
for (RestSection restSection : restSectionList) {
HashMap<String, String> sectionDisplay = new HashMap<>();
sectionDisplay.put("msectionid", String.valueOf(restSection.getMsectionid()));
sectionDisplay.put("msectionname", restSection.getMsectionname());
restSectionArrayList.add(sectionDisplay);
}
/* listView = (ListView) findViewById(R.id.seclist);
sectionLazyAdapter = new SectionLazyAdapter(this, restSectionArrayList);
listView.setAdapter(sectionLazyAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int sectionId = restSectionList.get(position).getMsectionid();
Log.d("Sectionid is ", String.valueOf(sectionId));
*//*Intent intent = new Intent(GroupSectionActivity.this, GroupSectionActivity.class);
intent.putExtra("groupid", groupAccountId);
intent.putExtra("sectionid", sectionId);
startActivity(intent);
finish();*//*
}
});
addSectionButton = (Button) findViewById(R.id.sectionAddButton);
addSectionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int val = addGroupSection();
if (val == 0) {
sectionName.setError("Section Name cannot be null");
} else {
sectionName.clearComposingText();
sectionName.clearAnimation();
sectionName.setText("");
Toast.makeText(getApplicationContext(), "Section added", Toast.LENGTH_LONG).show();
}
}
});*/
}
public Integer addGroupSection(){
/* sectionName = (EditText) findViewById(R.id.sectionNameTextField);
if (!(sectionName.getText().toString().isEmpty())) {
RestSection restSection = new RestSection();
restSection.setMsectionname(sectionName.getText().toString());
return this.sectionService.addGroupSection(restSection,canvasid);
}
*/
return 0;
}
@Override
public void onBackPressed() {
Intent intent = new Intent(GroupSectionActivity.this, GroupCanvasActivity.class);
intent.putExtra("groupid", groupAccountId);
startActivity(intent);
finish();
}
private NoteFragments getSectionsFragment() {
return (NoteFragments) getFragmentManager().findFragmentByTag(msectionname);
}
}
SectionLazyAdapter :
public class SectionLazyAdapter extends BaseAdapter{
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public SectionLazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.activity_group_section, null);
TextView sectionName = (TextView)vi.findViewById(R.id.sectionname); // title
HashMap<String, String> sectionList = new HashMap<String, String>();
sectionList = data.get(position);
sectionName.setText(sectionList.get(GroupSectionActivity.msectionname));
return vi;
}
}
注意适配器:
public class NoteAdapters extends RecyclerView.Adapter<NoteViewHolder> {
private NoteServiceImpl noteService = new NoteServiceImpl();
private static final int LINEAR = 0;
private final Context mContext;
private SectionServiceImpl sectionService = new SectionServiceImpl();
List<RestSection> restSectionList = new ArrayList<>();
private final ArrayList<LineItem> mItems;
public NoteAdapters(Context context, int headermode) {
mContext = context;
int sectionManager = -1;
int sectionFirstPosition = 0;
mItems = new ArrayList<>();
restSectionList = this.sectionService.getSectionByCanvas(2500);
for (int i = 0; i < restSectionList.size(); i++) {
String header = restSectionList.get(i).getMsectionname();
RestNote restNote = this.noteService.getFirstNoteForSection(restSectionList.get(i).getMsectionid());
mItems.add(new LineItem(header, true, sectionManager, sectionFirstPosition, restNote.getMnotetext()));
}
}
@Override
public NoteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_group_section, parent, false);
return new NoteViewHolder(view);
}
@Override
public void onBindViewHolder(NoteViewHolder holder, int position) {
final LineItem item = mItems.get(position);
final View itemView = holder.itemView;
holder.bindText(item.text);
holder.bindNoteData(item.otherText);
final GridSLM.LayoutParams lp = GridSLM.LayoutParams.from(itemView.getLayoutParams());
lp.setSlm(item.sectionManager == LINEAR ? LinearSLM.ID : GridSLM.ID);
lp.setColumnWidth(mContext.getResources().getDimensionPixelSize(R.dimen.grid_column_width));
lp.setFirstPosition(item.sectionFirstPosition);
itemView.setLayoutParams(lp);
}
@Override
public int getItemCount() {
return mItems.size();
}
/* @Override
public void onClick(View v) {
if(v instanceof ImageView){
Log.d("Image","Clicked");
} else {
Log.d("Text","Clicked");
}
}*/
private static class LineItem {
public int sectionManager;
public int sectionFirstPosition;
public boolean isHeader;
public String text;
public String otherText;
public LineItem(String text, boolean isHeader, int sectionManager,
int sectionFirstPosition, String otherText) {
this.isHeader = isHeader;
this.text = text;
this.sectionManager = sectionManager;
this.sectionFirstPosition = sectionFirstPosition;
this.otherText = otherText;
}
}
}
笔记 fragment :
public class NoteFragments extends Fragment {
private ViewHolder mViews;
private NoteAdapters noteAdapters;
private int mHeaderDisplay;
private boolean mAreMarginsFixed;
private Random mRng = new Random();
private Toast mToast = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.section_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mViews = new ViewHolder(view);
mViews.initViews(new LayoutManager(getActivity()));
noteAdapters = new NoteAdapters(getActivity(), mHeaderDisplay);
mViews.setAdapter(noteAdapters);
}
@Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
}
private static class ViewHolder {
private final RecyclerView mRecyclerView;
public ViewHolder(View view) {
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
}
public void initViews(LayoutManager lm) {
mRecyclerView.setLayoutManager(lm);
}
public void scrollToPosition(int position) {
mRecyclerView.scrollToPosition(position);
}
public void setAdapter(RecyclerView.Adapter<?> adapter) {
mRecyclerView.setAdapter(adapter);
}
public void smoothScrollToPosition(int position) {
mRecyclerView.smoothScrollToPosition(position);
}
}
}
笔记 View 持有者:
public class NoteViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
private TextView noteData;
private ImageView imageView;
public NoteViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.sectionname);
imageView = (ImageView) itemView.findViewById(R.id.sectionimage);
noteData = (TextView) itemView.findViewById(R.id.noteText);
}
public void bindText(String text){
textView.setText(text);
}
public void bindImage(Bitmap bitmap){
imageView.setImageBitmap(bitmap);
}
public void bindNoteData(String data){
noteData.setText(data);
}
}
XML 文件:activity_group_section.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip" >
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:orientation="vertical">
<ImageView
android:id="@+id/sectionimage"
android:layout_width="140dp"
android:layout_height="200dp"
android:scaleType="fitXY"
android:padding="5dp"
android:src="@drawable/sectionbackground"
/>
<TextView
android:id="@+id/sectionname"
android:layout_width="90dp"
android:layout_height="match_parent"
android:text="@string/textView"
android:visibility="visible"
android:gravity="center"
android:layout_gravity="center_horizontal|top"
android:maxLines="1"
android:ellipsize="end"
android:scrollHorizontally="true"
android:layout_marginTop="10dp" />
<TextView
android:layout_width="97dp"
android:layout_height="160dp"
android:id="@+id/noteText"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="10dp"
android:layout_marginTop="30dp" />
</FrameLayout>
</RelativeLayout>
部 fragment 段:
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:clipToPadding="false"
android:layout_height="wrap_content" />
Section 和 Notes 的模型类:
public class RestSection {
private int msectionid;
private String msectionname;
private int mxposition;
private int myposition;
private int msectionwidth;
private int msectionheight;
}
public class RestNote {
private int mnoticesid;
private String mnotetext;
private String mnotetag;
private String mnotecolor;
private double mnoteorder;
}
我希望我的问题很清楚,如果有任何需要,请告诉我。
最佳答案
您实际上已经非常接近实现了,但有几件事需要注意。您的顶级网格设置为使用 ListView/GridView 适配器,而您的第二级网格设置为 RecyclerView.Adapters。一旦您知道自己在做什么,这一切都很好。但是,我建议一直使用一个或另一个(最好是 RecyclerView.Adapters,因为它们更具可扩展性)。不过,为简单起见,我将使用您当前的设置给出解决方案:
顶级(BaseAdapter/ListAdapter + GridView)
您应该将整个数据集传递给顶级适配器,例如RestSection 的 ArrayList 而不是 HashMap 的 ArrayList。如果需要此数据,HashMap 可能是 RestSection 的成员,但似乎可以用一个简单的字符串替换它。 RestSection 数据结构还应该有一个成员,它是一个 RestNotes 列表。这个适配器的项目 View 应该有一个 RecyclerView,在你的例子中它在 NoteFragment 里面。这可能会替换 activity_group_section.xml 中的 noteText。在适配器的 getView() 中,您应该使用属于该部分的注释设置此 RecyclerView 的适配器。有关详细信息,请参阅以下代码 fragment 。
数据结构:
public class RestSection {
private int msectionid;
private String msectionname;
private int mxposition;
private int myposition;
private int msectionwidth;
private int msectionheight;
private List<RestNote> mnotes;
}
public class RestNote {
private int mnoticesid;
private String mnotetext;
private String mnotetag;
private String mnotecolor;
private double mnoteorder;
}
SectionLazyAdapter:
public class SectionLazyAdapter extends BaseAdapter{
private List<RestSection> data;
//...
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.activity_group_section, null);
RestSection mySection = data.get(position);
TextView sectionName = (TextView)vi.findViewById(R.id.sectionname); // title
sectionName.setText(mySection.getSectionName());
NoteFragments noteGridView = (NoteFragments) vi.findViewById(R.id.notegridfragment);
noteGridView.setRecyclerViewAdapter(new NoteAdapter(mySection.getNotes()));
return vi;
}
}
activity_group_section.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip" >
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:orientation="vertical">
<ImageView
android:id="@+id/sectionimage"
android:layout_width="140dp"
android:layout_height="200dp"
android:scaleType="fitXY"
android:padding="5dp"
android:src="@drawable/sectionbackground"
/>
<TextView
android:id="@+id/sectionname"
android:layout_width="90dp"
android:layout_height="match_parent"
android:text="@string/textView"
android:visibility="visible"
android:gravity="center"
android:layout_gravity="center_horizontal|top"
android:maxLines="1"
android:ellipsize="end"
android:scrollHorizontally="true"
android:layout_marginTop="10dp" />
<fragment android:name="com.mypackagename.NoteFragments"
android:layout_width="97dp"
android:layout_height="160dp"
android:id="@+id/notegridfragment"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="10dp"
android:layout_marginTop="30dp" />
</FrameLayout>
</RelativeLayout>
二级(RecyclerView.Adapter + RecyclerView)
这个适配器应该将注释列表作为它的数据集(如上面的 SectionLazyAdapter 所示)。像以前一样使用 Note 数据填充 UI。请参阅下面的代码 fragment 。
笔记 fragment :
public class NoteFragments extends Fragment {
private RecyclerView noteGridView;
// ...
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// as before
noteGridView = (RecyclerView) view;
}
public void setRecyclerViewAdapter(NoteAdapter adapter){
noteGridView.setAdapter(adapter);
}
}
笔记适配器:
public class NoteAdapters extends RecyclerView.Adapter<NoteViewHolder> {
private List<RestNote> mItems;
public NoteAdapters(List<RestNote> notes) {
super();
mItems = notes;
}
@Override
public void onBindViewHolder(NoteViewHolder holder, int position) {
// populate as before... make sure that RestNote has all of the data required
}
}
当然,您必须将数据重新排序为所需的格式,但我认为以这种方式显示数据会更容易。
希望对您有所帮助。
关于java - 安卓 : Putting Grid of dynamic&custom objects inside another Grid of dynamic&custom objects,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31983291/
我在大学学习C++时学习了这段代码..后来我在C#中使用了同样的东西...但现在我想在Java中使用它...我在互联网上寻找类似的东西,但我什至不知道如何表达它,以便我得到正确的结果。 所以嗯,请让我
我正在我的 Ruby on Rails Controller 上运行 RSPEC 测试,这是我正在测试的 Controller 操作: Controller 代码: class Customers::
想为我选择的选项卡设置自定义背景,到目前为止,子类化是我自定义 UITAbBar/UITabBarItem 的方式。 问题是:有谁知道(或知道我在哪里可以找到)设置背景的属性是什么? 所选选项卡周围有
您好,我在 commerefacades-beans.xml 中创建了 eProductForm bean,我添加了 ProductData 的自定义属性。 然后在commercewebs
我有两个表:1. 客户2. customer_order 客户表包含客户数据(duh),customer_order 包含所有订单。我可以在 customer.id=customer_order.id
在我的 TableView 中,我有一个 NSMutableArray *currList 的数据源 - 它包含对象 Agent 的对象。我创建了自定义的 TableCell 并正确设置了所有内容。我
是否建议使用自引用泛型继承? public abstract class Entity { public Guid Id {get; set;} public int Version
我正在尝试为我的 Grafana 安装使用自定义文件 ( custom.ini )。不幸的是,这不起作用。 我做了什么: 安装了一台装有 CentOS 7 的虚拟机 添加了 Grafana Yum R
我被分配了两个给定类的作业,一个是抽象父类 Lot.java,另一个是测试类 TestLots.java。我不应该编辑其中任何一个。任务是创建Lot的两个子类,使TestLots中的错误不再是错误。
我是 Botpress 的新手。 我刚刚安装了 Botpress 的最新版本“botpress-ce-v11_0_1-win-x64”。 我浏览了文档,发现了一些关于内容类型、内容元素和内容渲染的解释
我一直在四处寻找,但我还没有找到任何东西,除了 Qt3 的旧文档和 qt 设计器的 3.x 版。 我会举个例子,并不是因为我的项目是 GPL 而不能提供代码,而是为了简单起见。 示例:您正在为您的应用
场景 我有一个自定义规则来验证订单的运费: public class OrderValidator : BaseValidator { private string CustomInfo {
我有用于身份验证的自定义拦截器: @Named("authInterceptor") @Provides @Singleton fun providesAuthIntercep
如果有人没有添加照片,我想显示默认头像图像。我假设我需要在模型或助手中执行自定义 getter。 如果我做 getter,它会看起来像这样吗: def avatar_url "default_ur
我正在使用 Google Search API,但遇到了一些麻烦。这个请求(在 Python 中,使用 requests 库)工作正常 res = requests.get("https://www.
我使用 MSKLC 制作了自定义键盘布局。 我以为我仔细按照说明操作了chose appropriate values对于LOCALENAME和 LOCALID参数。 但是,在通过按 Win+Spac
我正在使用 simpleframework解析 XML 字符串并将其转换为对象。 Serializer serializer = new Persister(); try { Customer
我正在使用 C# 控制台应用程序从 MySql 数据库获取一些数据,但在正确查询时遇到一些问题 现在的情况: SELECT * FROM Customer WHERE EXISTS ( SELECT
我在我的 iPhone 4S 上运行我的应用程序,我正在使用自定义表格 View Controller 和自定义表格 View 单元格,当我将表格 View 向上滑动到空白区域并同样向下滑动到空白区域
我有一个自定义的 JavaScript 变量,它正在检查 eventAction 是什么,这样我就可以知道是否触发一些转换像素。自定义 Javascript 称为“FacebookConversion
我是一名优秀的程序员,十分优秀!