简体   繁体   中英

How can I make the Views defined in Android XML customs view file visible

I've the below code, that is having one element as shown in the XML file below it, and a call of the custom view named card

package tk.zillion.app1;

import tk.zillion.app1.CustomViews.Card;

public class EmptyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_empty);
        RelativeLayout rl;
        rl = (RelativeLayout) findViewById(R.id.activity_empty);
        rl.addView(new Card(this));
    }
}

Below is the XML file, and how the layout appear in the Android studio:

在此处输入图片说明

The Card custom view is as below code and XML file:

package tk.zillion.app1.CustomViews;

import tk.zillion.app1.R;

public class Card extends RelativeLayout {
    public Card(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    public Card(Context context, AttributeSet attrs){
        super(context, attrs);
        init(context);
    }
    public Card(Context context) {
        super(context);
        init(context);
    }
    private void init(Context context) {
        WindowManager windowmanager = (WindowManager) this.getContext()
                                        .getSystemService(Context.WINDOW_SERVICE);

        Display display = windowmanager.getDefaultDisplay();

        Point size = new Point();
        display.getSize(size);
        int width = size.x;
        int height = size.y;
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
                                                                         LayoutParams.WRAP_CONTENT);;
        RelativeLayout rl = new RelativeLayout(this.getContext());
        rl.setBackground(context.getDrawable(R.drawable.layer_card_background));
        rl.setMinimumWidth(width);
        Button btn = new Button(this.getContext());
     //   btn.setId(R.id.titleId);
        btn.setId(View.generateViewId());
        TextView one = new TextView(this.getContext());
        one.setText("Device width is: "+String.valueOf(width)+", Device height is: "+String.valueOf(height));
        one.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);

        btn.setText(R.string.custom);
        btn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                int duration = Toast.LENGTH_SHORT;
                CharSequence text = "Hello from another toast!";
                Toast toast = Toast.makeText(v.getContext(), text, duration);
                toast.show();
            }
        });
        rl.addView(btn);
        lp.addRule(RelativeLayout.BELOW, btn.getId());
        rl.addView(one, lp);
        // or one.setLayoutParams(lp);  rl.addView(one);
        //  lp.removeRule(RelativeLayout.BELOW);
        this.addView(rl);
    }
}

and the XML file is:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/custom_view"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
    <tk.zillion.app1.CustomViews.Card
        android:id="@+id/custom_card"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    <TextView android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        />
    </tk.zillion.app1.CustomViews.Card>
</RelativeLayout>

and appeared in Android studio as:

在此处输入图片说明

Below is how the app looks at execution (Right side), and how it should be (Left side). The View defined in the XML file, that is the My First App TextView, is not appearing at the execution, while all other elements defined pragmatically are visible.

在此处输入图片说明

I tried to use inflate but did not work with me

My Question is how can I the View, the ones defined in the XML file are visible?

Try this xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/custom_view"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
    <TextView android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        />

    <tk.zillion.app1.CustomViews.Card
        android:id="@+id/custom_card"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

I found the answer, and will detailed it below, may some one in the future get help from it:

1 . there was no need for using <tk.zillion.app1.CustomViews.Card> so I restructured my view_customs.xml to be:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/custom_view"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >

    <TextView android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        />
</LinearLayout>

2 . It looks I was wrongly using the inflater, so re-wote it to match the:

inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) inflation statement, where itInflates a new view hierarchy from the specified XML node.

3 . The final structure of my Card class init method, became:

private void init(Context context) {
      // 1. Define the main layout of the CARD class
      RelativeLayout cardLayout = new RelativeLayout(this.getContext());

     // 2. (Optional) set the require specs for this Layout
    cardLayout.setBackground(
              context.getDrawable(R.drawable.layer_card_background));
    cardLayout.setMinimumWidth(width);

    // 3. Inflate the custom view
    LayoutInflater inflater = LayoutInflater.from(context);
    View inflatedLayout= inflater.inflate(R.layout.view_customs, null, false);

    // 4. Set ID for the inflated view
    inflatedLayout.setId(View.generateViewId());

    // 5. (Optional) pick and change the elements in the custom view
    TextView otv = (TextView) inflatedLayout.findViewById(R.id.tv);
    otv.setText("Welcome to my first app");


    /*
       You can avoid point 3, 4 and 5, if you do not want to infalte from existing layout, simply use:
     View inflatedLayout = new View(this.getContext());
    */

    // 6. (Optional) create new elements
    Button btn = new Button(this.getContext());
    btn.setId(View.generateViewId());
    btn.setText(R.string.custom);
    btn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
                int duration = Toast.LENGTH_SHORT;
                CharSequence text = "Hello from another toast!";
                Toast toast = Toast.makeText(v.getContext(), text, duration);
                toast.show();
        }
    });

    TextView one = new TextView(this.getContext());
    one.setText("Device width is: ");
    one.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);

    // 7. Locate the relative locations between the inflated element and the main Layout
    RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(
                                 ViewGroup.LayoutParams.WRAP_CONTENT,
                                 ViewGroup.LayoutParams.WRAP_CONTENT);
    p.addRule(RelativeLayout.BELOW, inflatedLayout.getId());
    cardLayout.setLayoutParams(p);

    // 8. In the same way as of 7, locate the relative locations of the elements inside the main Layout itself.
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                     LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        lp.addRule(RelativeLayout.BELOW, btn.getId());

   // 9. Add the inflated Layout, and all other elements to the main Layout
   cardLayout.addView(inflatedLayout);
   cardLayout.addView(btn);
   cardLayout.addView(one, lp);

   // 10. Add the main Layout to the class
   this.addView(cardLayout);  

    // 11. In the same way, you need to locate the returned CARD
    // in relative location in the view that calling it
    RelativeLayout.LayoutParams p1 = new RelativeLayout.LayoutParams(
                                 ViewGroup.LayoutParams.WRAP_CONTENT,
                               //  ViewGroup.LayoutParams.WRAP_CONTENT
                                  150);
    p1.addRule(RelativeLayout.BELOW, R.id.checkBox);
    this.setLayoutParams(p1);
}
  1. (Optional) for the custom card drawable background, I used the below code:

     <?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <stroke android:width="2dp" android:color="#FFFFFFFF" /> <solid android:color="#FFFFFFFF" /> <corners android:bottomRightRadius="7dp" android:bottomLeftRadius="7dp" android:topLeftRadius="7dp" android:topRightRadius="7dp" /> </shape> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM