Android 从类向父活动添加ImageView

Android 从类向父活动添加ImageView,android,position,imageview,parent,Android,Position,Imageview,Parent,我想创建一个灵活的类,我可以放入我创建的任何项目中。此类将生成一个映像(最终是来自服务器的映像),并将其放置在调用活动的视图中 其思想是:一个活动创建这个类的一个实例,当我想显示这个图像时,我调用这个类的“show”方法,传递x和y坐标、宽度和高度,以及一个默认的图像名称,如果它不能从服务器加载一个图像的话 我很难使我创建的ImageView在父活动中正确定位。我尝试了许多不同的方法,但到目前为止,我在课堂上得到的是: public class ImageProducer {

我想创建一个灵活的类,我可以放入我创建的任何项目中。此类将生成一个映像(最终是来自服务器的映像),并将其放置在调用活动的视图中

其思想是:一个活动创建这个类的一个实例,当我想显示这个图像时,我调用这个类的“show”方法,传递x和y坐标、宽度和高度,以及一个默认的图像名称,如果它不能从服务器加载一个图像的话

我很难使我创建的ImageView在父活动中正确定位。我尝试了许多不同的方法,但到目前为止,我在课堂上得到的是:

public class ImageProducer 
{   
        //parent activity
        Activity parentActivity;

    public void show(int x, int y, int imageWidth, int imageHeight, String defaultImage)
    {
        Resources r = parentActivity.getResources();
        String packageName = parentActivity.getPackageName();
        String imagePath = packageName + ":drawable/" + defaultImage;
        int rID = r.getIdentifier(imagePath,null,null);
        ImageView v = new ImageView(parentActivity.getBaseContext());
        v.setImageResource(rID);
        v.setScaleType(ScaleType.FIT_CENTER);
        AbsoluteLayout.LayoutParams lp = new AbsoluteLayout.LayoutParams(imageWidth, imageHeight, x, y);
        v.setLayoutParams(lp);
        parentActivity.addContentView(v, lp);
    }

    public ImageProducer(Activity a)
    {
        parentActivity = a;

    }
}
图像显示在父活动中,但始终将其自身定位在左上角

关于如何在我的课堂上定位它,有什么想法吗?棘手的部分是父活动没有设置布局


非常感谢

我可以想出一两种方法

您可以确保所有活动布局的根布局都是一个
RelativeLayout
,然后使用必要的参数将视图添加到该视图中,使其在视图中居中。这意味着布局是
RelativeLayout
中的第一个子项,您的图像作为第二个子项添加,因此将显示在第一个子项的顶部

通过扩展
视图组
,可以创建自己的布局管理器。您可能需要对其进行一些调整,但本质上这就是
ViewGroup
的外观

public class Article2 extends ViewGroup {

    private View layout;
    private ImageView theImage;
    private Context ctx;

public Article2(Context context,View layout) {
    super(context);
    ctx = context;
    this.layout = layout;
    this.addView(layout);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
    int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSpecSize =  MeasureSpec.getSize(widthMeasureSpec);

    int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSpecSize =  MeasureSpec.getSize(heightMeasureSpec);

    for(int i = 0;i<this.getChildCount();i++){
        final View child = this.getChildAt(i);
        measureChild(child, widthMeasureSpec, heightMeasureSpec);   
    }
    setMeasuredDimension(widthSpecSize, heightSpecSize);
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    layout.layout(left, top, right, bottom);

    if(theImage!= null){
        theImage.layout(right/2 - theImage.getMeasuredHeight()/2, bottom/2 -theImage.getMeasuredHeight()/2, right/2 + theImage.getMeasuredHeight()/2, bottom/2 + theImage.getMeasuredHeight()/2);
    }

}

public void startImage(String url){
    theImage = new ImageView(ctx);
    new GetImage(url).execute();
}

private class GetImage extends AsyncTask<Void,Void,Boolean>{
String url=null;
public GetImage(String url){
    this.url = url;
}
@Override
protected Boolean doInBackground(Void... arg0) {
    if(url!=null&&url.length()>0){

        try {
            theImage.setImageBitmap(BitmapFactory.decodeStream((InputStream)new URL(url).getContent()));
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        return true;

    }else{
        return false;
    }
}
@Override
protected void onPostExecute(Boolean addView){
    if(addView){
            addView(theImage);
    }
}
}
}
而是这样做

Article2 article2;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v = inflater.inflate(R.layout.MyLayout, null);
    article2 = new Article2(this,v);
    setContentView(article2);
}
通过这种方式,上面的5行就是您需要投入到每个活动中以使其工作的全部内容

要显示图像,只需调用
parentActivity.article2.startImage(url)
,它会在屏幕中央的视图上方放置一个图像


需要注意的是,我没有在那里放置任何东西来删除图像,一旦图像被放置,您可能只需要使用
第2条。removeViewAt(1)
,但我还没有对此进行测试。

仅供参考,以下是我为使事情正常运行而做的事情:我将ImageView添加到parentActivity中,之后,我抓起一个指向布局参数的指针。LayoutParams是FrameLayout,因此我必须设置重力,然后指定x和y值。我的代码是这样的:

    Resources r = parentActivity.getResources();
        String packageName = parentActivity.getPackageName();
        packageName+=":drawable/" + defaultImage;
        int rID = r.getIdentifier(packageName,null,null);
        ImageView v = new ImageView(parentActivity.getBaseContext());
        v.setImageResource(rID);

        parentActivity.addContentView(v, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams();
        lp.width=w;
        lp.height=h;
        lp.gravity=Gravity.LEFT | Gravity.TOP;
        lp.leftMargin=x;
        lp.topMargin=y;
        v.setLayoutParams(lp);
        v.requestLayout();

再次感谢所有的建议

AbsoluteLayout已弃用,不建议使用。谢谢,Emil。我知道绝对布局不受欢迎;我最后尝试了一下,作为最后的努力来指定ImageView应该放在哪里。谢谢你,triggs。我会仔细考虑你的建议,看看它们是否符合我的需要
    Resources r = parentActivity.getResources();
        String packageName = parentActivity.getPackageName();
        packageName+=":drawable/" + defaultImage;
        int rID = r.getIdentifier(packageName,null,null);
        ImageView v = new ImageView(parentActivity.getBaseContext());
        v.setImageResource(rID);

        parentActivity.addContentView(v, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams();
        lp.width=w;
        lp.height=h;
        lp.gravity=Gravity.LEFT | Gravity.TOP;
        lp.leftMargin=x;
        lp.topMargin=y;
        v.setLayoutParams(lp);
        v.requestLayout();