为清楚起见,已解决并编辑了内容。
相关参考:
Android ADT 版本 22,未生成 R.java 文件
在 Eclipse 中为 Android 开发:R.java 未重新生成
在运行时创建 NinePatch/NinePatchDrawable
https://code.google.com/p/android-apktool/wiki/9PatchImages
问题:我如何以编程方式(即运行时而不是通过 XML 定义)将我的九个补丁引用到 R.java 中,以便我可以从中调用它EmployeeAdapter::getView()
?
回答:
- 要运行时/以编程方式为所有视图对象 设置相同的九个补丁背景,请在返回对象之前在内部执行
view.setBackgroundResource(R.drawable.blue_fill)
Adapter::getView(...)
- 要运行时/以编程方式分别为每个视图对象设置九个补丁背景,请
setBackgroundResource(R.drawable.blue_fill)
在View::onDraw(...)
.- 确保您的实现
View::onDraw(Canvas c)
不会覆盖您的 9.png,例如c.drawColor(color)
.- 将您的文件 (blue_fill.9.png) 放在正确
/res/drawable-*/
的文件夹中(为了安全起见!)- 我读过九个补丁文件需要全部小写。(注意安全,去做吧!)
- 有一种语法可以在 XML 文件中定义九个补丁(我不确定如何准确利用它,并且超出了这个范围),但我可以向您保证,我不需要它。事实上,我强烈怀疑我的工作空间问题是在我创建
/res/drawable-mdpi/blue_fill.xml
并/res/drawable-mdpi/blue_fill.9.png
使用 XML 语法链接到我的之后出现的。这可能是错误的!- 随意在下面借用我的工作代码。
- 因为 /res/、/layout/ 的错误会导致各种问题,并且可能会导致工作空间被占用,所以 在编辑 XML 或其他非 .java 文件时 要小心。(1)始终检查 LogCat、问题、控制台输出,(2)查看 Eclipse 的错误日志,最后 (3)彻底查看您的构建配置以查看问题是否仍然存在(仔细检查 ADT v22 中的新“项目>属性> Java Build Path> Order and Export ”,并确保您的源代码不会影响Order 更高级别的现有库!
回答我的问题:
由于完全独立于 ADT 22 的原因,我的工作区不再重新生成
R.java
. 我怀疑我弄乱/res/drawable-*/
文件夹导致了我的问题。我删除了除ic_launcher.png
from之外的所有文件/res/drawable-*/
,试图将我的工作区恢复到原始状态。我还怀疑我导入了不正确的 R 库(你应该导入的唯一import com.example.yourproject.R
一个是)
原始问题:我可以使用bl_fill.9.png
我的 XML 定义的GridView
. 但是,当我尝试以编程方式将其分配bl_fill.9.png
给我的View
对象时,EmployeeAdapter::getView(...)
我得到一个编译时错误,即bl_fill cannot be resolved or is not a field
.
我花了很多天试图解决这个问题。任何帮助深表感谢!
环境:
- ADT : v22
- Android SDK 工具:rev22
- Android SDK 平台工具:rev17
- Android SDK 构建工具:rev17
- 目标 API:Android 4.1 Jelly Bean(API 级别 16)
- 最高 API:Android 4.2 Jelly Bean(API 级别 17)
尝试:
- 错误的 /res/drawable-*/ 文件夹?
我尝试了一个文件夹中的所有图片。我尝试了所有文件夹中的所有图片。这些图片似乎在任何地方都可以很好地采购,因为GridView
从不为找不到图片资源而打嗝。
- 糟糕的九个补丁?
为了揭穿它可能是格式不正确的 *.9.png,我尝试了其中的几个(我下载了所有这些),并且每个都在我的 XML 定义的 GridView 上工作。
- 成功代码:
/res/layout/activity_main.xml :这里用XML定义了GridView,我成功分配了9个补丁bl_fill
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:numColumns="5"
android:columnWidth="90dp"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
android:background="@drawable/bl_fill"
/>
/res/drawable-xxhdpi/ xxhdpi-9p.xml:我知道编译器需要这个文件来将“来源”九补丁(包含控制像素的 1px 边框)转换为“编译”九补丁(添加“块”元数据并剥离所有控制像素)。但更重要的是,我明白int R.java.drawable.bl_fill
应该从这个文件定义中生成
<?xml version="1.0" encoding="utf-8"?>
<nine-patch
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/bl_fill"/>
- 不成功的代码(已更新,现在可以使用):
但是,它似乎R.java
正在为其他资源生成int
引用,但只是固执地不会为bl_fill
.
EmployeeAdapter.java
package com.stackoverflow.signinboard;
import java.util.List;
import android.R;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
// useful "Good Practices" for Adapters referenced at
// http://www.piwai.info/android-adapter-good-practices/
//
// also
// http://androidadapternotifiydatasetchanged.blogspot.in/
/**
* An adapter that abstracts the structure of a database and safely exposes
* information to consumers.
*
* {@link GridView} uses this to obtain self-draw information for itself and
* {@link EmployeeView} children
*/
public class EmployeeAdapter extends BaseAdapter {
private Context mContext;
private List<Employee> mEmployees;
public EmployeeAdapter(Context c, List<Employee> employees) {
mContext = c;
mEmployees = employees;
}
@Override
/**
* Returns the total number of employees
*/
public int getCount() {
return mEmployees.size();
}
/**
* Returns the specified employee
*
* @param arg0
* Index of the employee in database
*/
@Override
public Object getItem(int arg0) {
return mEmployees.get(arg0);
}
/**
* Not implemented.
*/
@Override
public long getItemId(int arg0) {
return 0;
}
/**
* Gets the EmployeeView specified by 'index'.
*
* @param index
* Index of this employee in the database
* @param convertView
* Reference to a View that may or may not be initialized
* @param parent
* Viewgroup that this View is associated with
* @return An initialized EmployeeView at the specified index
*/
@Override
public View getView(int index, View convertView, ViewGroup parent) {
EmployeeView employeeView;
// Recylce reference if possible, else instantiate a new EmployeeView
if (convertView == null) {
// Instantiate an Employeeview with the ID and state
// and define its parameters
employeeView = new EmployeeView(mContext, mEmployees.get(index)
.getmEmployeeId(), mEmployees.get(index).getState());
employeeView.setLayoutParams(new GridView.LayoutParams(150, 85));
employeeView.setPadding(8, 8, 8, 8);
employeeView.setBackgroundResource(R.drawable.bl_fill);
} else {
// Set new values for the ID and state of this EmployeeView
employeeView = (EmployeeView) convertView;
employeeView.initEmployee(mEmployees.get(index).getmEmployeeId(),
mEmployees.get(index).getState());
}
return employeeView;
}
}