所以我制作了这个用于梦境分析的应用程序,它在手机上运行良好,但在平板电脑上,explists 中的信息会混合在一起,如下图所示。
也就是说,当您单击该组时,它应该隐藏/显示它的子项,但如您所见,在平板电脑上它只是继续一个接一个地绘制信息,就像显示器不会刷新其内容一样,我有不知道该怎么做,因此向您寻求帮助。
容器布局:
<?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="match_parent"
android:orientation="vertical"
android:paddingBottom="10dp">
<ExpandableListView
android:id="@+id/sExpList"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:groupIndicator="@null" />
<!-- FOR PORTRAIT LAYOUTS !-->
<FrameLayout
android:id="@+id/adLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginTop="5dp"
android:baselineAligned="false"
android:orientation="vertical"/>
</LinearLayout>
群元素代码:
<?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="match_parent"
android:orientation="horizontal"
>
<TextView
android:id="@+id/textGroup"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:textStyle="bold"
android:textSize="@dimen/text_normal_size" />
<ImageButton
android:id="@+id/sExp_BtnAdd"
android:layout_width="@dimen/btns_heigh"
android:layout_height="@dimen/btns_heigh"
android:layout_gravity="center_vertical"
android:contentDescription=""
android:focusable="false"
android:scaleType="centerCrop"
android:src="?attr/img_add" />
</LinearLayout>
子元素代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textChild"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textColor="@android:color/white"
android:layout_weight="1"
android:textSize="@dimen/text_normal_size" />
<ImageButton
android:layout_width="@dimen/btns_heigh"
android:layout_height="@dimen/btns_heigh"
android:id="@+id/sExp_BtnEdit"
android:layout_gravity="center_vertical"
android:src="?attr/img_edit"
android:scaleType="centerCrop"
android:focusable="false"
android:layout_marginRight="@dimen/btns_heigh" />
</LinearLayout>
Activity 代码:
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
/**
* Created with IntelliJ IDEA.
* User: Movsar Bekaev
* Date: 11.06.13
* Time: 7:30
* To change this template use File | Settings | File Templates.
*/
public class ActSignsManager extends cbActivity {
ExpandableListView expListView;
int selected_type;
String[] cats;
ArrayList<xSign> MySigns;
_sManagerExpAdapter adapter;
String[] catsMind;
String[] catsAction;
String[] catsForm;
String[] catsCircumstances;
private void cInitialization() {
setContentView(R.layout.alay_signs_manager);
catsMind = getResources().getStringArray(R.array.smanager_cats_mind);
catsAction = getResources().getStringArray(R.array.smanager_cats_action);
catsForm = getResources().getStringArray(R.array.smanager_cats_form);
catsCircumstances = getResources().getStringArray(R.array.smanager_cats_circumstances);
expListView = (ExpandableListView) findViewById(R.id.sExpList);
newSignFunc();
readSigns();
expFiller();
adapter.notifyDataSetChanged();
expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
String s = MySigns.get(SignIndexAt(selected_type, groupPosition, adapter.getChild(groupPosition, childPosition).toString())).getTitle();
Toast.makeText(ActSignsManager.this, String.valueOf(s), Toast.LENGTH_LONG).show();
return false;
}
});
expListView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
String menuItems[];
ExpandableListView.ExpandableListContextMenuInfo info =
(ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
int type = ExpandableListView.getPackedPositionType(info.packedPosition);
int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition);
if (type == 0) {
menuItems = getResources().getStringArray(R.array.exp_menu_ongroup);
menu.setHeaderTitle(adapter.getGroupText(groupPos));
for (int i = 0; i < menuItems.length; i++) {
menu.add(Menu.NONE, i, i, menuItems[i]);
}
}
if (type == 1) {
String s = adapter.getChild(groupPos, childPos).toString();
menuItems = getResources().getStringArray(R.array.exp_menu_onchild);
menu.setHeaderTitle(s);
for (int i = 0; i < menuItems.length; i++) {
menu.add(Menu.NONE, i, i, menuItems[i]);
}
}
}
});
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.DarkTheme);
cInitialization();
}
@Override
public boolean onContextItemSelected(MenuItem item) {
ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) item.getMenuInfo();
int menuItemIndex = item.getItemId();
int type = ExpandableListView.getPackedPositionType(info.packedPosition);
int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition);
if (type == 0) {
switch (menuItemIndex) {
case 0:
Intent i = new Intent(ActSignsManager.this, ActSignsAddNew.class);
ps_int_params.put("Type", selected_type);
ps_string_arr_params.put("Categories", cats);
ps_int_params.put("Selected_Item", groupPos);
if (IS_FREE_VERSION && MySigns.size() > 69)
Toast.makeText(ActSignsManager.this, getString(R.string.ruefully_you_cant_add_another_sign), Toast.LENGTH_LONG).show();
else startActivity(i);
break;
}
}
if (type == 1) {
int index = SignIndexAt(selected_type, groupPos, adapter.getChild(groupPos, childPos).toString());
switch (menuItemIndex) {
case 0:
// Toast.makeText(sManager.this, "edit", 5000).show();
Intent i = new Intent(ActSignsManager.this, ActSignsAddNew.class);
ps_int_params.put("ID", MySigns.get(index).getID());
ps_string_params.put("Name", MySigns.get(index).getTitle());
ps_int_params.put("Type", MySigns.get(index).getType());
ps_int_params.put("Category", MySigns.get(index).getCategory());
ps_string_params.put("Note", MySigns.get(index).getNote());
ps_string_arr_params.put("Categories", cats);
startActivity(i);
break;
}
}
return true;
}
// нажатие на элемент
void newSignFunc() {
String type = ps_string_params.get("Type");
if (type.equals("Mind")) {
cats = catsMind;
selected_type = 0;
}
if (type.equals("Action")) {
cats = catsAction;
selected_type = 1;
}
if (type.equals("Form")) {
cats = catsForm;
selected_type = 2;
}
if (type.equals("Circumstances")) {
cats = catsCircumstances;
selected_type = 3;
}
}
private void readSigns() {
MySigns = new ArrayList<xSign>();
Cursor c = ps_db.query(const_tbl_signs, null, null, null, null, null, null);
if (c != null) {
if (c.moveToFirst()) {
do {
xSign iSingleSign = new xSign();
iSingleSign.setID(c.getInt(DBI_SIGNS_ID));
iSingleSign.setHash(c.getString(DBI_SIGNS_HASH));
iSingleSign.setTitle(c.getString(DBI_SIGNS_TITLE));
iSingleSign.setType(c.getInt(DBI_SIGNS_TYPE));
iSingleSign.setCategory(c.getInt(DBI_SIGNS_CATEGORY));
iSingleSign.setNote(c.getString(DBI_SIGNS_NOTE));
MySigns.add(iSingleSign);
Log.d("777", iSingleSign.getID() + "||| cat:" + iSingleSign.getCategory() + "||| type:" + iSingleSign.getType());
} while (c.moveToNext());
c.close();
} else
Log.d("777", "0 rows");
}
}
private int SignIndexAt(int type, int category, String name) {
boolean exist = false;
int index = -1;
for (int i = 0; i < this.MySigns.size(); i++) {
if (this.MySigns.get(i).getTitle().equals(name) && this.MySigns.get(i).getCategory() == category && this.MySigns.get(i).getType() == type) {
index = i;
exist = true;
}
}
if (exist) {
return index;
} else {
return 999999;
}
}
private boolean removeSign(int index) {
ps_db.delete(const_tbl_signs, "id = " + MySigns.get(index).getID(), null);
Toast.makeText(ActSignsManager.this, getString(R.string.messages_sign_removed), Toast.LENGTH_LONG).show();
// Refresh main activity upon close of dialog box
readSigns();
expFiller();
adapter.notifyDataSetChanged();
return true;
}
private void expFiller() {
ArrayList<String> tmp;
ArrayList<ArrayList<String>> groups = new ArrayList<ArrayList<String>>();
for (int i = 0; i < cats.length; i++) {
tmp = new ArrayList<String>();
for (xSign sign : MySigns) {
if (sign.getCategory() == i && sign.getType() == selected_type)
tmp.add(sign.getTitle());
}
groups.add(tmp);
}
//Создаем адаптер и передаем context и список с данными
adapter = new _sManagerExpAdapter(this, cats, groups);
expListView.setAdapter(adapter);
}
@Override
public void onResume() {
super.onResume();
cInitialization();
showAds();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
cInitialization();
showAds();
}
public class _sManagerExpAdapter extends BaseExpandableListAdapter {
private ArrayList<ArrayList<String>> mGroups;
private Context mContext;
private String[] cats;
public _sManagerExpAdapter(Context context, String[] categories, ArrayList<ArrayList<String>> groups) {
mContext = context;
mGroups = groups;
cats = categories;
}
public String getGroupText(int groupPosition) {
return cats[groupPosition];
}
@Override
public int getGroupCount() {
return mGroups.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return mGroups.get(groupPosition).size();
}
@Override
public Object getGroup(int groupPosition) {
return mGroups.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return mGroups.get(groupPosition).get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.s_exp_group_view, null);
}
if (isExpanded) {
//Изменяем что-нибудь, если текущая Group раскрыта
} else {
//Изменяем что-нибудь, если текущая Group скрыта
}
TextView textGroup = (TextView) convertView.findViewById(R.id.textGroup);
textGroup.setText(cats[groupPosition] + " [" + String.valueOf(this.getChildrenCount(groupPosition)) + "]");
ImageView btnAddSigns = (ImageView) convertView.findViewById(R.id.sExp_BtnAdd);
btnAddSigns.setFocusable(false);
final int gPos = groupPosition;
btnAddSigns.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(ActSignsManager.this, ActSignsAddNew.class);
ps_int_params.put("Type", selected_type);
ps_string_arr_params.put("Categories", cats);
ps_int_params.put("Selected_Item", gPos);
if (IS_FREE_VERSION && MySigns.size() > 69)
Toast.makeText(ActSignsManager.this, getString(R.string.ruefully_you_cant_add_another_sign), Toast.LENGTH_LONG).show();
else startActivity(i);
}
});
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.s_exp_child_view, null);
}
TextView textChild = (TextView) convertView.findViewById(R.id.textChild);
textChild.setText(mGroups.get(groupPosition).get(childPosition));
final int index = SignIndexAt(selected_type, groupPosition, adapter.getChild(groupPosition, childPosition).toString());
ImageView btnEditSign = (ImageView) convertView.findViewById(R.id.sExp_BtnEdit);
btnEditSign.setFocusable(false);
btnEditSign.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(ActSignsManager.this, ActSignsAddNew.class);
ps_int_params.put("ID", MySigns.get(index).getID());
ps_string_params.put("Name", MySigns.get(index).getTitle());
ps_int_params.put("Type", MySigns.get(index).getType());
ps_int_params.put("Category", MySigns.get(index).getCategory());
ps_string_params.put("Note", MySigns.get(index).getNote());
ps_string_arr_params.put("Categories", cats);
startActivity(i);
}
});
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
}
最佳答案
我能够让它工作,但我得到的错误与你的略有不同。
当我尝试使用您的布局(减去我没有的资源)时,group_element.xml 和 child_element.xml 中的 ImageButton code> 以某种方式捕获整行中的 MotionEvent(当它们不应该捕获时),在我的例子中,它扰乱了布局的扩展。
解决方案:我只是为两个 ImageView 使用了两个 ImageButton,并为这两个 View 构建了 OnTouchListener。如您所见,它正在 Nexus 7 模拟器上运行。
因为我没有你的数据集,最重要的是适配器代码,所以我不能肯定地说这会解决你的问题。
请注意,如果您有兴趣,我已经在 ExpandableListViews 上的 JournalDev 适配器示例的自定义版本上测试了您的 XML。 :
import java.util.HashMap;
import java.util.List;
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class CustomExpandableListAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> expandableListTitle;
private HashMap<String, List<String>> expandableListDetail;
public CustomExpandableListAdapter(Context context, List<String> expandableListTitle,
HashMap<String, List<String>> expandableListDetail) {
this.context = context;
this.expandableListTitle = expandableListTitle;
this.expandableListDetail = expandableListDetail;
}
@Override
public Object getChild(int listPosition, int expandedListPosition) {
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.get(expandedListPosition);
}
@Override
public long getChildId(int listPosition, int expandedListPosition) {
return expandedListPosition;
}
@Override
public View getChildView(int listPosition, final int expandedListPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final String expandedListText = (String) getChild(listPosition, expandedListPosition);
if (convertView == null) {
//---------------------------------------------
LayoutInflater layoutInflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.child_element, null);
}
TextView expandedListTextView = (TextView) convertView
.findViewById(R.id.textChild);
expandedListTextView.setText(expandedListText);
ImageView editViewBtn = (ImageView)convertView.findViewById(R.id.sExp_BtnEdit);
editViewBtn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// do stuff
return false;
}
});
return convertView;
}
@Override
public int getChildrenCount(int listPosition) {
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.size();
}
@Override
public Object getGroup(int listPosition) {
return this.expandableListTitle.get(listPosition);
}
@Override
public int getGroupCount() {
return this.expandableListTitle.size();
}
@Override
public long getGroupId(int listPosition) {
return listPosition;
}
@Override
public View getGroupView(int listPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String listTitle = (String) getGroup(listPosition);
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.group_element, null);
}
TextView listTitleTextView = (TextView) convertView
.findViewById(R.id.textGroup);
listTitleTextView.setTypeface(null, Typeface.BOLD);
listTitleTextView.setText(listTitle);
ImageView addV = (ImageView)convertView.findViewById(R.id.sExp_BtnAdd);
addV.setVisibility(View.VISIBLE);
addV.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// do stuff
return false;
}
});
return convertView;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int listPosition, int expandedListPosition) {
return true;
}
}
虚拟数据生成器:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class ExpandableListDataPump {
public static HashMap<String, List<String>> getData() {
HashMap<String, List<String>> expandableListDetail = new HashMap<String, List<String>>();
List<String> ego = new ArrayList<String>();
ego.add("dream 1");
ego.add("dream 2");
ego.add("dream 3");
ego.add("dream 4");
ego.add("dream 5");
List<String> personalities = new ArrayList<String>();
personalities.add("dream 1");
personalities.add("dream 2");
personalities.add("dream 3");
personalities.add("dream 4");
List<String> places = new ArrayList<String>();
places.add("dream 1");
places.add("dream 2");
places.add("dream 3");
places.add("dream 4");
places.add("dream 5");
expandableListDetail.put("Form of the ego", ego);
expandableListDetail.put("Form of other personalities", personalities);
expandableListDetail.put("Place's form", places);
return expandableListDetail;
}
}
主要 Activity :
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Main4Activity extends AppCompatActivity {
ExpandableListView expandableListView;
ExpandableListAdapter expandableListAdapter;
List<String> expandableListTitle;
HashMap<String, List<String>> expandableListDetail;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
expandableListView = (ExpandableListView) findViewById(R.id.sExpList);
expandableListDetail = ExpandableListDataPump.getData();
expandableListTitle = new ArrayList<>(expandableListDetail.keySet());
expandableListAdapter = new CustomExpandableListAdapter(this, expandableListTitle, expandableListDetail);
expandableListView.setAdapter(expandableListAdapter);
expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
@Override
public void onGroupExpand(int groupPosition) {
Toast.makeText(getApplicationContext(),
expandableListTitle.get(groupPosition) + " List Expanded.",
Toast.LENGTH_SHORT).show();
}
});
expandableListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
@Override
public void onGroupCollapse(int groupPosition) {
Toast.makeText(getApplicationContext(),
expandableListTitle.get(groupPosition) + " List Collapsed.",
Toast.LENGTH_SHORT).show();
}
});
expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
Toast.makeText(
getApplicationContext(),
expandableListTitle.get(groupPosition)
+ " -> "
+ expandableListDetail.get(
expandableListTitle.get(groupPosition)).get(
childPosition), Toast.LENGTH_SHORT
).show();
return false;
}
});
}
}
您的主 xml 略有变化,不要忘记从 ImageButton 切换到 ImageView:
(我改了一些你没有分享的资源和维度)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="10dp">
<ExpandableListView
android:id="@+id/sExpList"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:groupIndicator="@null" />
<!-- FOR PORTRAIT LAYOUTS !-->
<FrameLayout
android:id="@+id/adLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginTop="5dp"
android:baselineAligned="false"
android:orientation="vertical"/>
</LinearLayout>
组 xml:
<?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="match_parent"
android:orientation="horizontal"
>
<TextView
android:id="@+id/textGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="17dp"
android:layout_marginTop="2dp"
android:layout_weight="7"
android:textStyle="bold"
android:textSize="13sp" />
<ImageView
android:id="@+id/sExp_BtnAdd"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_gravity="center_vertical"
android:contentDescription=""
android:focusable="false"
android:scaleType="centerCrop"
android:src="@android:drawable/ic_input_add" />
</LinearLayout>
子xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textChild"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="?android:attr/expandableListPreferredItemPaddingLeft"
android:layout_marginTop="2dp"
android:textColor="@android:color/white"
android:layout_weight="1"
android:textSize="13sp" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginEnd="?android:attr/expandableListPreferredItemPaddingLeft"
android:id="@+id/sExp_BtnEdit"
android:layout_gravity="center_vertical"
android:src="@android:drawable/ic_menu_edit"
android:scaleType="centerCrop"
android:focusable="false"
android:layout_marginRight="5dp" />
</LinearLayout>
呃...这是一篇很长的文章,希望对您有所帮助!
关于android - ExpandableListView 的项目混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40255606/
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我正在尝试创建一个带有项目符号字符的Ruby1.9.3字符串。str="•"+"helloworld"但是,当我输入它时,我收到有关非ASCII字符的语法错误。我该怎么做? 最佳答案 你可以把Unicode字符放在那里。str="\u2022"+"helloworld" 关于ruby-如何在Ruby字符串中插入项目符号字符?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1195
我的Rails站点使用了一个确实不是很好的gem。每次我需要做一些新的事情时,我最终不得不花费与向实际Rails项目添加代码一样多的时间来为gem添加功能。但我不介意,我将我的Gemfile设置为指向我的gem的GitHub分支(我尝试提交PR,但维护者似乎已经下台)。问题是我真的没有找到一种合理的方法来测试我添加到gem的新东西。在railsc中测试它会特别好,但我能想到的唯一方法是a)更改~/.rvm/gems/.../foo。rb,这看起来不对或者b)升级版本,推送到Github,然后运行bundleup,这除了耗时之外显然是一场灾难,因为我不确定我所做的promise是否正
我有一个模块:moduleMyModuledefdo_something#...endend由类使用如下:classMyCommandextendMyModuledefself.execute#...do_somethingendend如何验证MyCommand.execute调用了do_something?我已经尝试使用mocha进行部分模拟,但是当未调用do_something时它不会失败:it"callsdo_something"doMyCommand.stubs(:do_something)MyCommand.executeend 最佳答案
所以我只是对此感到好奇:DataMapper为其模型使用混合classPostincludeDataMapper::Resource虽然active-record使用继承classPost有谁知道为什么DataMapper选择这样做(或者为什么AR选择不这样做)? 最佳答案 它允许您从另一个不是DM类的类继承。它还允许动态地将DM功能添加到类中。这是我正在处理的模块中的类方法:defdatamapper_classklass=self.dupklass.send(:include,DataMapper::Resource)klass