LinearLayoutで子ビューが中央に来ない？ setGravity と layoutParams.gravity の違い

## はじめに
javaのコードでレイアウトをするときに、LinearLayoutを使って
親要素の中で子のリニアレイアウトを上下中央配置にしたかった時に試した備忘録。
setGravityとGravityって何が違うの？

結論、`setGravity(Gravity.CENTER)`を親の`LinearLayout`に付与すれば子のLinearLayoutは上下中央配置になる。
```java
 parent.setGravity(Gravity.CENTER);
 ```

## setGravity　と　layoutParams.gravity
GPTさんに聞いてみた
| 書き方                                     | 対象             | 効果                                    |
| --------------------------------------- | -------------- | ------------------------------------- |
| `setGravity(Gravity.CENTER)`            | **親ViewGroup** | 親の中で **子要素の配置位置** を決める                |
| `layoutParams.gravity = Gravity.CENTER` | **子View**      | 子が **親の中でどこに配置されたいか** を伝える |

さすが。
setGravityは　「親がここにいなさい！」と命令するのに対し
layoutParams.gravityは　「子が親にここに居たい！」とお願いするイメージっぽい
ただし、LinearLayoutの時、後者の子から親にお願いするおねだりは却下されるっぽい。（うまく配置されない）

## 具体例
親に`setGravity(Gravity.CENTER)`を付与した時
```java

// 親ビュー
        LinearLayout parent = new LinearLayout(this);
        LinearLayout.LayoutParams parentParam = new LinearLayout.LayoutParams(1000,500);
        parent.setGravity(Gravity.CENTER); // ←　ここ注目。
        parent.setBackgroundColor(Color.GRAY);
        addContentView(parent, parentParam);
// 子ビュー
        LinearLayout child = new LinearLayout(this);
        LinearLayout.LayoutParams childParam = new LinearLayout.LayoutParams(500,250);
        child.setBackgroundColor(Color.WHITE);
        parent.addView(child, childParam);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032633/1ff2e62d-9eca-4f9a-b2b2-f252a89560f0.png)

親ビューの中で子ビューが上下中央配置される。　問題なし。


### 
子に`layoutParams.gravity = Gravity.CENTER`を付与したとき
※（間違った方法）

```java
// 親ビュー
        LinearLayout parent = new LinearLayout(this);
        LinearLayout.LayoutParams parentParam = new LinearLayout.LayoutParams(1000,500);
        // parent.setGravity(Gravity.CENTER);　ここで指定せず
        parent.setBackgroundColor(Color.GRAY);
        addContentView(parent, parentParam);
// 子ビュー
        LinearLayout child = new LinearLayout(this);
        LinearLayout.LayoutParams childParam = new LinearLayout.LayoutParams(500,250);
        childParam.gravity = Gravity.CENTER;　// ←ここ追加。
        child.setBackgroundColor(Color.WHITE);
        parent.addView(child, childParam);
 ```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032633/42ee2961-d6c4-402e-9d70-d0dff5e77e1a.png)

左寄りの上下中央になる。（なんでそうなるのか詳しくはわからない。。）

親が LinearLayout の場合、子にgravityをつけても効きません！とのことらしい。
LinearLayout の配置は、**主に 親側の setGravity()** でコントロールするとのこと。

## 子→親で上下中央配置にしたいときは？
`FrameLayout.LayoutParams` なら有効らしい。

```java
// 親ビュー
        FrameLayout parent = new FrameLayout(this); //　← ここをFrameLayout
        FrameLayout.LayoutParams parentParam = new FrameLayout.LayoutParams(1000,500);//　←　ここをFrameLayout
        parent.setBackgroundColor(Color.GRAY);
        addContentView(parent, parentParam);
// 子ビュー
        LinearLayout child = new LinearLayout(this);
        FrameLayout.LayoutParams childParam = new FrameLayout.LayoutParams(500, 250);//←　ここをFrameLayout
        childParam.gravity = Gravity.CENTER;
        child.setBackgroundColor(Color.WHITE);
        parent.addView(child, childParam);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032633/1ff2e62d-9eca-4f9a-b2b2-f252a89560f0.png)

うまくいってる。

## まとめ

-  LinearLayoutの場合、子に`layoutParams.gravity` を使っても親内で上下中央配置にはできない
-  LinearLayoutの場合、子を親内で上下中央配置したい場合、親で`setGravity`をする必要がある。
-  子→親で上下中央配置したい場合は`FrameLayout`を利用するとうまくいく。

今回は中央寄せでしたが、STARTとかENDとかCENTER_HORIZONTALとかもうまくいく方法ではうまくいく。
以上、備忘録でした。

※てか`FrameLayout`って何という新たな疑問がうまれたので後ほど勉強。