我在Android开发方面绝对是新手,我正在开发我的第一个关于Udacity初学者课程的教育应用程序。
应用程序的想法非常简单:它是一个cousine recipes应用程序,其中使用从recepy交换到另一个交换在主活动中向右或向左滑动。
这是我与此应用程序相关的 GitHub 存储库:https://github.com/AndreaNobili/PastaFromRome
要从recepy转换到另一个我使用该片段,所以基本上我有一个 activity_man.xml 文件,该文件只包含标题和该片段的viewpager:
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
然后我有 fragment_screen_slide_page.xml ,表示与单个食谱相关的幻灯片,如下所示:
<!-- Dummy content. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="0dp">
<ImageView
android:id="@+id/imageView1"
android:layout_width="fill_parent"
android:scaleType="fitXY"
android:layout_height="250dp" />
<!--
android:src="@drawable/carbonara"/>
android:background="@drawable/carbonara" />
-->
<TextView android:id="@android:id/text1"
style="@style/pastaTitleTextStyle" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0px"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
style="@style/HeaderTextStyle"
android:text="Difficoltà:" />
<ImageView
android:id="@+id/difficultyContainer"
android:layout_width="fill_parent"
android:scaleType="fitXY"
android:layout_height="55dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
此视图是一个碎片,当显示时,包含当前配方。
它包含第一个 ImageView ,ID imageView1 ,显示与当前食谱相关的图像,效果很好。
然后它包含第二个 ImageView ,其ID为 difficultyContainer ,这是在运行时从应用程序创建的难度排名图像。这是我疯狂的地方!!!
这是处理片段逻辑的 ScreenSlidePageFragment 类(扩展 Fragment ):
/**
* A fragment representing a single step in a wizard. The fragment shows a dummy title indicating
* the page number, along with some dummy text.
*
*/
public class ScreenSlidePageFragment extends Fragment {
private static final String TAG = "ScreenSlidePageFragment";
/**
* The argument key for the page number this fragment represents.
*/
public static final String ARG_PAGE = "page";
/**
* The fragment's page number, which is set to the argument value for {@link #ARG_PAGE}.
*/
private int mPageNumber;
private static Context context;
/**
* Factory method for this fragment class. Constructs a new fragment for the given page number.
*/
public static ScreenSlidePageFragment create(int pageNumber, Context baseContext) {
ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
Bundle args = new Bundle();
args.putInt(ARG_PAGE, pageNumber);
fragment.setArguments(args);
context = baseContext;
return fragment;
}
public ScreenSlidePageFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageNumber = getArguments().getInt(ARG_PAGE);
}
/**
* Method that will be called when the "pasta slider" is slided right or left
* @param inflater
* @param container
* @param savedInstanceState
* @return
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
System.out.println("PAGE NUMBER: "+ mPageNumber);
// Obtain the colosseum_icon.png from the rsources as a Drawable:
//Drawable drawable = getResources().getDrawable(R.drawable.colosseum_icon);
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_screen_slide_page, container, false);
ImageView imgSlideView = (ImageView) rootView.findViewById(R.id.imageView1);
/* Retrieve the ImageView having id="difficultyContainer" (where to put the diifficulty
image created):
*/
//ImageView difficultyContainerImageView = (ImageView) rootView.findViewById(R.id.difficultyContainer);
// Load the 2 images for the creation of the "difficulty graphic":
Bitmap chefHatWhite = BitmapFactory.decodeResource(getResources(), R.drawable.chef_hat_white);
Bitmap chefHatOk = BitmapFactory.decodeResource(getResources(), R.drawable.chef_hat_ok);
// Where the previus image will be drawn:
//Canvas canvas = new Canvas();
Canvas difficultyCanvas = creaImgDifficulty();
//switch (mPageNumber + 1) {
switch (mPageNumber) {
case 0:
imgSlideView.setImageResource(R.drawable.carbonara);
((TextView) rootView.findViewById(android.R.id.text1)).setText(getString(R.string.carbonara));
ImageView difficultyContainerImageView1 = (ImageView) rootView.findViewById(R.id.difficultyContainer);
difficultyContainerImageView1.setImageDrawable(new BitmapDrawable(getResources(), ImgUtility.createRankingImg(context, 3)));
break;
case 1:
imgSlideView.setImageResource(R.drawable.amatriciana);
((TextView) rootView.findViewById(android.R.id.text1)).setText(getString(R.string.amatriciana));
break;
case 2:
imgSlideView.setImageResource(R.drawable.gricia_m);
((TextView) rootView.findViewById(android.R.id.text1)).setText(getString(R.string.gricia));
break;
case 3:
imgSlideView.setImageResource(R.drawable.cacio_e_pepe);
((TextView) rootView.findViewById(android.R.id.text1)).setText(getString(R.string.cacio_e_pepe));
break;
case 4:
imgSlideView.setImageResource(R.drawable.ajo_ojo_e_peperoncino);
((TextView) rootView.findViewById(android.R.id.text1)).setText(getString(R.string.ajo_ojo_peperoncino));
break;
}
return rootView;
}
private void createImg(ImageView imgview) {
Canvas canvas;
Bitmap star = BitmapFactory.decodeResource(getResources(), R.drawable.star);
Bitmap output = Bitmap.createBitmap(32, 32, Bitmap.Config.ARGB_8888);
canvas = new Canvas(output);
canvas.drawBitmap(star, star.getWidth() + 2, 0, null);
imgview.setImageDrawable(new BitmapDrawable(getResources(), output));
}
private Canvas creaImgDifficulty() {
Canvas canvas;
Bitmap chefHatOk = BitmapFactory.decodeResource(getResources(), R.drawable.chef_hat_ok);
Bitmap output = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
canvas = new Canvas(output);
int space = 10; // the space between images
for(int i = 0; i < 3; i++) {
canvas.drawBitmap(chefHatOk, i * (chefHatOk.getWidth() + space), 0, null);
}
return canvas;
}
/**
* Returns the page number represented by this fragment object.
*/
public int getPageNumber() {
return mPageNumber;
}
}
所以基本上进入 onCreateView()方法(我认为是在加载当前片段时执行的)我有 mPageNumber 变量来指定与之相关的加载片段一个特定的配方,有一个 switch case ,用于将此配方的特定信息加载到此片段中,例如:
案例0:这是第一个名为 carbonara 的食谱,所以它将 carbonara.png 图像(R.drawable.carbonara)放入上一个 ImageView 在 fragment_screen_slide_page.xml 文件中定义了 id = imageView1 。
工作正常。
在我之前的代码中出现问题:
ImageView difficultyContainerImageView1 = (ImageView) rootView.findViewById(R.id.difficultyContainer);
difficultyContainerImageView1.setImageDrawable(new BitmapDrawable(getResources(), ImgUtility.createRankingImg(context, 3)));
正如您在代码中看到的那样, difficultyContainerImageView1 标识了片段中 id = difficultyContainer 的 ImageView 。在这里,我设置了一个由 ImgUtility.createRankingImg()方法创建的图像。
public class ImgUtility {
/**
* Method that create the images related to the difficulty of a recepy
* @param context
* @param difficulty that represent the number of chef_hat_ok into the final image
* @return a Bitmap representing the difficult of a recepy
*/
public static Bitmap createRankingImg(Context context, int difficulty) {
// Create a Bitmap image starting from the star.png into the "/res/drawable/" directory:
Bitmap myBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.chef_hat_ok);
// Create a new image bitmap having width to hold 5 star.png image:
Bitmap tempBitmap = Bitmap.createBitmap(myBitmap.getWidth() * 5, myBitmap.getHeight(), Bitmap.Config.RGB_565);
Canvas tempCanvas = new Canvas(tempBitmap);
// Draw the image bitmap into the cavas:
tempCanvas.drawBitmap(myBitmap, 0, 0, null);
tempCanvas.drawBitmap(myBitmap, myBitmap.getWidth(), 0, null);
tempCanvas.drawBitmap(myBitmap, myBitmap.getWidth() * 2, 0, null);
tempCanvas.drawBitmap(myBitmap, myBitmap.getWidth() * 3, 0, null);
tempCanvas.drawBitmap(myBitmap, myBitmap.getWidth() * 4, 0, null);
return tempBitmap;
}
}
这个方法应该没问题,因为在我看来,它返回一个Bitmap但是这个图像没有显示在 id = abilityContainer
的片段 ImageView 中进入logcat我可以看到以下错误日志,但我不知道是否与我的问题有关:
08-21 19:38:12.315 4239-4925/com.example.android.pastafromrome W/OpenGLRenderer: Bitmap too large to be uploaded into a texture (8730x1836, max=4096x4096)
08-21 19:38:12.335 4239-4925/com.example.android.pastafromrome W/OpenGLRenderer: Bitmap too large to be uploaded into a texture (8730x1836, max=4096x4096)
08-21 19:38:12.335 4239-4925/com.example.android.pastafromrome W/OpenGLRenderer: Bitmap too large to be uploaded into a texture (8730x1836, max=4096x4096)
为什么呢?我错过了什么?我该如何解决这个问题?如果您看到我的GitHub存储库并帮我修复它,我将非常高兴。
答案 0 :(得分:1)
问题是Android会自动将 chef_hat_ok 的大小调整为1746px宽度(我想这取决于设备)。它似乎没问题,但你做了其中5个而5 x 1746px是8370并且纹理无法容纳。
解决方案:禁用缩放或放置取决于密度的资源(未检查该选项)。
禁用缩放。
ImgUtility.java
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
Bitmap myBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.chef_hat_ok, options);
编辑:您需要将密度设置为画布tempCanvas.setDensity(myBitmap.getDensity());
Edit2:我还建议对难度容器进行一些更改
<ImageView
android:id="@+id/difficultyContainer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:adjustViewBounds="true" />